跨多线程的单一事务解决方案
据我所知,所有事务都是线程绑定的(即上下文存储在ThreadLocal中)。例如,如果:
- 我在事务性父方法中启动事务
- 在异步调用中使数据库插入 #1
- 在另一个异步调用中插入数据库 #2
然后,这将产生两个不同的事务(每个插入一个),即使它们共享相同的“事务”父级。
例如,假设我执行两个插入(并使用一个非常简单的示例,即不使用执行器或可简化的未来,等等):
@Transactional
public void addInTransactionWithAnnotation() {
addNewRow();
addNewRow();
}
将根据需要将两个插入作为同一事务的一部分执行。
但是,如果我想并行化这些插入以提高性能:
@Transactional
public void addInTransactionWithAnnotation() {
new Thread(this::addNewRow).start();
new Thread(this::addNewRow).start();
}
然后,这些生成的线程中的每一个都不会参与事务,因为事务是线程绑定的。
关键问题:有没有办法安全地将事务传播到子线程?
我想到的解决这个问题的唯一解决方案:
- 使用 JTA 或一些 XA 管理器,根据定义,它们应该能够做到这一点。但是,理想情况下,我不想在我的解决方案中使用XA,因为它的开销很大
- 将我想要执行的所有事务性工作(在上面的示例中为函数)管道传输到单个线程,并以多线程方式完成所有先前的工作。
addNewRow()
- 想办法利用TransitableThreadLocal在事务状态上并将其传播到子线程。我不知道该怎么做。
有没有可能的解决方案?即使它的味道有点像解决方法(就像我上面的解决方案一样)?