使用CountDownLatch解决实际业务问题过程
使用的技术比较简单,主要记录下思考和解决的过程
业务背景:
1、高管在页面对审批申请单进行审批(调用submit()方法)
2、新的产品需求,要在审批提交时,同步执行另外的一系列操作(已有现成的doExecute()方法,直接调用即可)
3、数据库为MySQL(事务的隔离级别为默认,可重复读),代码中事务由spring事务管理器管理
开发过程:
直接在submit()方法中新起一个线程调用doExecute()方法
出现问题:
测试过程中发现部分数据状态未正常更新,排查代码逻辑未发现问题,后发现submit()方法更新了A表,doExecute()方法也更新了A表,这两个方法是在不同的线程中执行的,属于不同的事务,后提交的事务会覆盖前一事务提交的信息。
解决方法
1、改成同步调用doExecute()方法。之后发现,doExecute()方法逻辑非常复杂,执行时间较长,需要5.5秒中,原submit()方法执行时间约2.4秒,一共需要用户等待8秒,严重影响了用户体验,而且此用户一般为高管。
2、优化doExecute()业务逻辑代码。经过痛苦的业务逻辑梳理,代码优化后,执行时间减少了1.4秒,杯水车薪。
3、既然两个方法本就不需要同步执行,那我等submit方法执行完成之后,也就是事务提交之后再调用doExecute()方法即可。
ps:因为submi()方法使用的模板方法设计模式,而且只是在满足部分条件后才调用doExecute()方法,所以不能直接在submit()方法后直接调用doExecute()方法
4、让线程先后执行的方式有,Thread.join(),CyclicBarrier,CountDownLatch。一开始考虑到复用,使用CyclicBarrier,但是在多线程环境中,完全不能保证AB线程的先后顺序,然后使用join()方法,但是又发

本文记录了一次使用CountDownLatch解决并发业务场景的问题。在高管审批应用中,提交审批时需同步执行其他操作,但不同事务导致数据冲突。尝试同步调用、优化业务逻辑后,最终采用CountDownLatch确保submit方法完成并提交事务后再执行doExecute,避免了用户体验下降和并发问题。
最低0.47元/天 解锁文章
826

被折叠的 条评论
为什么被折叠?



