参考:
1.
错用synchronized和@Transactional被老板点名批量 - 云+社区 - 腾讯云
2.
Spring 中 @transactional 和 synchronized关键字同时使用时数据不同步_尔等同学的博客-CSDN博客
失效原因:synchronized控制结束时,事务还没提交,此时另外的线程过来又读取到旧数据。
查找解决方案:在网上找了好久,大部分都是两种方案,1:去掉@Transactional;2:把Synchronized扩大范围,包裹事务。
上面两种方案对我们的项目都不可取,原因如下:
1. @Transactional注解在我们的业务中是非常有用的;
2. Synchronized包裹范围不能太大,因为代码逻辑很复杂且多,如果范围太大那性能可就太差了。
但是方向上有两种处理:
1. 事务不能包裹Synchronized,要让Synchronized包裹事务。
2. db层面的加锁。
最终采用了select ...... for update。
原因如下:影响范围小,业务上可以接受悲观锁。
但是又有疑问了,为什么select ......for update管用,这个行锁是不让更新的,但是查询还是会重复啊。想了半天想不通,结果上面参考中的第二篇文章给我解答疑惑了。因为select ......for update会上锁,这时另外的想来select可以,但是select for update就不行了,要排队!所以可以实现理想的结果。
总结:具体的方案要根据实际的业务场景来调整,没有最好,只有最合适!