据我了解,所有事务都是线程绑定的(即上下文存储在ThreadLocal中).例如,如果:
然后,即使它们共享相同的"事务性"父级,也会产生两个不同的事务(每个插入一个).
例如,假设我执行两次插入(并使用非常简单的示例,即为了简洁起见,不使用执行程序或可完成的未来等):
@Transactional
public void addInTransactionWithAnnotation() {
addNewRow();
addNewRow();
}
Run Code Online (Sandbox Code Playgroud)
将根据需要执行两个插入作为同一事务的一部分.
但是,如果我想并行化这些插入的性能:
@Transactional
public void addInTransactionWithAnnotation() {
new Thread(this::addNewRow).start();
new Thread(this::addNewRow).start();
}
Run Code Online (Sandbox Code Playgroud)
然后,这些生成的线程中的每一个都不会参与事务,因为事务是线程绑定的.
关键问题:有没有办法将事务安全地传播到子线程?
我想到的解决这个问题的唯一解决方案:
addNewRow()函数)传递给单个线程,并以多线程方式执行所有先前的工作.有没有更多可能的解决方案?即使它的味道有点像解决方法(比如上面的解决方案)?
大多数关系数据库分四步处理JDBC/SQL查询:
我想知道"解析传入的查询"到底意味着什么?"计划/优化数据采集路径"是什么意思?
我需要使用JDBC将大量插入(即两位数百万)插入Oracle-DB.为此,我使用类似下面的类,灵感来自使用JDBC进行批量INSERTS的高效方法:
public class Inserter {
private final int batchSize;
private final Connection con; // with .setAutoCommit(false)
private final PreparedStatement ps;
private int currentSize = 0;
public Inserter(Connection con, PreparedStatement ps, int batchSize) {
this.con = con;
this.ps = ps;
this.batchSize = batchSize;
}
public void addInsert(Object[] vals) throws SQLException {
ps.clearParameters(); // should be redundant, but better safe than sorry
for (int i = 0; i < val.length; i++) {
this.ps.setObject(i + 1, vals[i]);
}
ps.addBatch(); …Run Code Online (Sandbox Code Playgroud) I'm having something like:
List<Data> dataList = stepts.stream()
.flatMap(step -> step.getPartialDataList().stream())
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
So I'm combining into dataList multiple lists from every step.
My problem is that dataList might run into OutOfMemoryError. Any suggestions on how I can batch the dataList and save the batches into db?
My primitive idea is to:
for (Step step : steps) {
List<Data> partialDataList = step.getPartialDataList();
if (dataList.size() + partialDataList.size() <= MAXIMUM_SIZE) {
dataList.addAll(partialDataList);
} else {
saveIntoDb(dataList);
dataList = new ArrayList<>();
}
} …Run Code Online (Sandbox Code Playgroud) 我对 java 和数据库比较陌生,因此请您帮助我进行代码优化。我有大约 20 个带有逗号分隔值的文本文件。每个文本文件有大约 10000 行基于每行中的第三个值,我将数据插入到不同的表中。每次我检查第三个值并使用不同的方法来保存这些数据。我的代码如下。有人可以告诉我这是否是执行此操作的正确方法。提前致谢。
public void readSave() throws SQLException
{
File dir = new File("C:\\Users\\log");
String url = Config.DB_URL;
String user= Config.DB_USERNAME;
String password= Config.DB_PASSWORD;
con= DriverManager.getConnection(url, user, password);
con.setAutoCommit(false);
String currentLine;
if (!dir.isDirectory())
throw new IllegalStateException();
for (File file : dir.listFiles()) {
BufferedReader br;
try {
br = new BufferedReader(new FileReader(file));
while ((currentLine = br.readLine()) != null) {
List<String> values = Arrays.asList(currentLine.split(","));
if (values.get(2).contentEquals("0051"))
save0051(values,con);
else if(values.get(2).contentEquals("0049"))
save0049(values,con);
else if(values.get(2).contentEquals("0021"))
save0021(values,con);
else if(values.get(2).contentEquals("0089"))
save0089(values,con);
if(statement!=null)
statement.executeBatch(); …Run Code Online (Sandbox Code Playgroud) java ×5
jdbc ×2
mysql ×2
sql ×2
concurrency ×1
database ×1
hibernate ×1
java-8 ×1
java-stream ×1
oracle ×1
parsing ×1
query-parser ×1
transactions ×1