1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 多线程事务回滚

多线程事务回滚

时间:2024-07-14 11:41:35

相关推荐

多线程事务回滚

场景

项目需要 导入一批数据,对数据进行切割,用多线程跑。

问题点

方法上增加@Transactional,对多线程无效,发生异常,子线程不会回滚,即使在子线程中增加@Transactional。

原因:线程不归spring容器管理,也就不指望通知回滚了。

上代码

1.将大数据进行切割

// apache自带切割api, num是对应想要切几段ListUtils.partition(list, num);

2、使用异常标志、发令枪控制各线程回滚

@Transactional(rollbackFor = Exception.class)public Result<String> dealData(int sheetMergeCount) {// todo 业务逻辑...// 切割数据List<List<Integer>> list = splitList(sheetMergeCount, 10);// 异常标志,AtomicBoolean保证线程安全AtomicBoolean isError = new AtomicBoolean(false);// 发令枪,长度是切割的子集合数量CountDownLatch countDownLatch = new CountDownLatch(list.size());for (List<Integer> integerList : list) {// 将任务放进线程池ThreadPoolUtil.exec(() -> {// 将事务操作放在新的类中,并开启事务extraService.upload(integerList, isError, countDownLatch);});}try {// 等所有线程都跑完,判断异常标识,有异常,进行主线程内回滚countDownLatch.await();if (isError.get()) {// 手动回滚TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();return Result.fail("系统异常,稍后重试");}return Result.success("success");} catch (Exception e) {TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();log.error("dealData发令枪异常", e);}return Result.fail("系统异常,稍后重试");}

@Service@Slf4jpublic class ExtraServiceImpl implements ExtraService {@Override@Transactional(rollbackFor = Exception.class)public void uploadData(List<Integer> integerList, AtomicBoolean isError, CountDownLatch countDownLatch) {try {// todo 业务逻辑} catch (Exception e) {log.error("ExtraService.uploadData异常", e);// 发生异常,进行标记isError.set(true);} finally {// 发令枪倒计时countDownLatch.countDown();}try {// 等所有线程都跑完,判断异常标识,有异常,线程内进行回滚countDownLatch.await();if (isError.get()) {// 手动回滚TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();}} catch (Exception e) {log.error("ExtraService.uploadData发令枪异常", e);// 手动回滚TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();}}}

ok!!!希望能帮到您,麻烦点个赞

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。