最近开发,有地方需要用到多线程,每个线程里面处理多个方法,过程中遇到了一个问题,我们使用平时的@Transactional注解,就是当前一个方法执行完成(比如插入操作),后一个方法是不会事务回滚的。当时觉得很不可思议,后来经过半天时间,终于挖出原因,并成功解决。
我这里先说明原因:多线程底层连接数据库的时候,时使用的线程变量(TheadLocal),所以,开多少线程理论上就会建立多少个连接,每个线程有自己的连接,事务肯定不是同一个了。
解决办法:我强制手动把每个线程的事务状态放到一个同步集合里面。然后如果有单个异常,循环回滚每个线程。
代码如下:
//先在开启多线程外面,定义一个同步集合:
List<TransactionStatus> transactionStatuses = Collections.synchronizedList(new ArrayList<TransactionStatus>());
//开启多线程
executorService.execute(new Runnable() {
@Override
public void run() {
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); // 事物隔离级别,开启新事务,这样会比较安全些。
TransactionStatus status = transactionManager.getTransaction(def); // 获得事务状态
transactionStatuses.add(status);
try{
//逻辑1
...
//逻辑2
...
}catch(Exception e){
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。