Dov*_*vmo 10 java concurrency multithreading transactions
据我了解,所有事务都是线程绑定的(即上下文存储在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()函数)传递给单个线程,并以多线程方式执行所有先前的工作.有没有更多可能的解决方案?即使它的味道有点像解决方法(比如上面的解决方案)?
首先,澄清一下:如果您想加速同一类型的多个插入,正如您的示例所示,通过在同一线程中发出插入并使用某种类型的批量插入,您可能会获得最佳性能。根据您的 DBMS,有多种可用技术,请查看:
至于您的实际问题,我个人会尝试将所有工作传输到工作线程。这是最简单的选项,因为您不需要搞乱ThreadLocals 或事务登记/除名。此外,一旦您将工作单元放在同一线程中,如果您足够聪明,您也许能够应用上面的批处理技术以获得更好的性能。
最后,将工作管道传输到工作线程并不意味着您必须有一个工作线程,您可以拥有一个工作线程池并实现一些并行性(如果它确实对您的应用程序有益)。从生产者/消费者的角度思考。
| 归档时间: |
|
| 查看次数: |
4106 次 |
| 最近记录: |