摘要:最近开发,有地方需要用到多线程,每个线程里面处理多个方法,过程中遇到了一个问题,我们使用平时的注解,就是当前一个方法执行完成比如插入操作,后一个方法是不会事务回滚的。
最近开发,有地方需要用到多线程,每个线程里面处理多个方法,过程中遇到了一个问题,我们使用平时的@Transactional注解,就是当前一个方法执行完成(比如插入操作),后一个方法是不会事务回滚的。当时觉得很不可思议,后来经过半天时间,终于挖出原因,并成功解决。
我这里先说明原因:多线程底层连接数据库的时候,时使用的线程变量(TheadLocal),所以,开多少线程理论上就会建立多少个连接,每个线程有自己的连接,事务肯定不是同一个了。
解决办法:我强制手动把每个线程的事务状态放到一个同步集合里面。然后如果有单个异常,循环回滚每个线程。
代码如下:
//先在开启多线程外面,定义一个同步集合: ListtransactionStatuses = Collections.synchronizedList(new ArrayList ()); //开启多线程 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){ } }
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/69581.html
摘要:起因及介绍在处理原始对账文件的时候,我将数据归类后批量存入相应的表中。结论事务只能管着开启事务的线程,其他子线程出了问题都感知不到,所以在多线程环境操作要慎重。高频容易搞死服务器,低频会阻塞自身程序。重试次数和超时时间根据业务情况设置。 起因及介绍 在处理原始对账文件的时候,我将数据归类后批量存入相应的表中。在持久化的时候,用了parallelStream(),想着同时存入很多表这样可...
摘要:和事务的关系关系型数据库某些消息队列等产品或中间件称为事务性资源,因为它们本身支持事务,也能够处理事务。事务的传播特性,,,,,,强制要求要有一个物理事务。外围事务不会被内部事务的回滚状态影响。不支持当前事务。 Spring和事务的关系 关系型数据库、某些消息队列等产品或中间件称为事务性资源,因为它们本身支持事务,也能够处理事务。 Spring很显然不是事务性资源,但是它可...
阅读 692·2023-04-25 17:54
阅读 2895·2021-11-18 10:02
阅读 1108·2021-09-28 09:35
阅读 615·2021-09-22 15:18
阅读 2801·2021-09-03 10:49
阅读 2986·2021-08-10 09:42
阅读 2532·2019-08-29 16:24
阅读 1230·2019-08-29 15:08