失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > java多线程事务处理

java多线程事务处理

时间:2021-10-10 09:13:12

相关推荐

java多线程事务处理

1.自定义事务管理器

@Componentpublic class SelfTransactionManager {private TransactionStatus transactionStatus;//获取事务源@Autowiredprivate PlatformTransactionManager platformTransactionManager;@Autowiredprivate TransactionDefinition transactionDefinition;/*** 手动开启事务*/public TransactionStatus begin() {transactionStatus = platformTransactionManager.getTransaction(transactionDefinition);return transactionStatus;}/*** 提交事务*/public void commit(TransactionStatus transactionStatus) {mit(transactionStatus);}/*** 回滚事务*/public void rollBack() {platformTransactionManager.rollback(transactionStatus);}}

2.业务中实现

@Service@AllArgsConstructorpublic class BookingInfoServiceImpl implements IBookingInfoService {private BookingInfoMapper bookingInfoMapper;private SelfTransactionManager selfTransactionManager;private TaskExecutor taskExecutor;//自定义的线程池@Override@Transactional(rollbackFor=Exception.class)public boolean test() {// 评论中有个兄弟提到主线程异常子线程还是提交数据了, InheritableThreadLocal使用错了,会让每个线程会复制独立一份变量,主线程子线程中都有一份自己的变量,所以下面的代码主线程修改成了false,子线程是得不到的,得到的始终是自己线程内的那个变量(采用AtomicBoolean已解决问题)// final InheritableThreadLocal<Boolean> IS_OK = new InheritableThreadLocal<>();// IS_OK.set(Boolean.TRUE);AtomicBoolean IS_OK = new AtomicBoolean(true);//子线程计数器CountDownLatch childMonitor = new CountDownLatch(1);//子线程结果集CopyOnWriteArrayList<Boolean> childResponse = new CopyOnWriteArrayList<>();//主线程计数器CountDownLatch mainMonitor = new CountDownLatch(1);/*** ================================子线程1=======================================*/CompletableFuture.runAsync(() -> {TransactionStatus transactionStatus = selfTransactionManager.begin();boolean result = false;try {//当前子线程开始插入数据//---------业务代码----------BookingInfo bookingInfo = new BookingInfo();bookingInfo.setCreateTime(DateUtil.date());bookingInfo.setPhoneNumber("13215592666");bookingInfo.setNickName("ceshi0");result = bookingInfoMapper.insertBookingInfo(bookingInfo) < 1 ? false : true;//---------业务代码----------//插入结果 true or falsechildResponse.add(result);//执行到这里,等待主线程执行完,因为当前子线程要拿到 IS_OK 的结果,IS_OK的结果由主线程决策mainMonitor.await();//根据主线程决策的IS_OK,判断是回滚还是提交if (IS_OK.get()) {//提交mit(transactionStatus);}else {//回滚selfTransactionManager.rollBack();}} catch (Exception e) {e.printStackTrace();//因为会发生异常 而主线程一直在 while (true) 循环 childResponse的size,这里一定要保证进行add,否则可能会出现死循环childResponse.add(result);//异常回滚selfTransactionManager.rollBack();} finally {//子线程执行完计数器-1childMonitor.countDown();}}, taskExecutor);/*** ================================主线程========================================*/try {//---------业务代码----------BookingInfo bookingInfo2 = new BookingInfo();bookingInfo2.setPhoneNumber("13215592000");bookingInfo2.setNickName("ceshi2");bookingInfo2.setCreateTime(new Date());boolean result = bookingInfoMapper.insertBookingInfo(bookingInfo2) < 1 ? false : true;//---------业务代码----------//主线程插入不成功,不成功让 IS_OK = false;if (!result) {throw new RuntimeException();}//循环获取子线程结果while (true) {if (childResponse.size() == 1) {break;}}System.out.println(childResponse.size());//子线程中存在不成功让 IS_OK = false;if (childResponse.contains(Boolean.FALSE)) {throw new RuntimeException();}} catch (Exception e) {e.printStackTrace();//IS_OK = false; 等待主线程走完子线程就能得知 IS_OK 为falseIS_OK.set(Boolean.FALSE);//这里抛出异常 是为了当前主线程事务自动进行回滚throw e;} finally {//到这个方法执行完就意味着mainMonitor中主线程走完了,接着子线程会开始执行mainMonitor.countDown();}return true;}}

如果觉得《java多线程事务处理》对你有帮助,请点赞、收藏,并留下你的观点哦!

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