据我所知,所有事务都是线程绑定的(即上下文存储在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()函数)传递给单个线程,并以多线程方式执行所有先前的工作.
>找出在Transaction状态上利用InheritableThreadLocal并将其传播到子线程的某种方法.我不知道该怎么做.
有没有更多可能的解决方案?即使它的味道有点像解决方法(如我上面的解决方案)?