记录项目中 spring 事务与分布式锁、mq消息发送使用不当的 bug
问题一
在当前项目中做了一个电子钱包功能,在操作电子钱包的业务中,要更新多张表数据,且存在并发操作钱包金额的情况,为了保证数据一致性且并发操作钱包金额都能成功,采用了事务+分布式锁的方式。
大致代码如下:
1 |
|
但是这样的代码在经过 jmeter 压测后,发现金额总是对不上。
问题分析
在上述代码中,先开启事务,再在事务中使用了 redis 分布式锁,防止并发问题,仔细分析后发现这是有问题的,在事务内开启锁,并发的请求会阻塞在事务内部,假如 A,B 两个请求同时过来,A 先开启事务获得锁,查询数据再操作完数据后,释放锁,但此时事务还没提交,B 获得锁,B 再查询的数据是 A 未提交的数据,所以数据肯定不一致。
解决方法
将开启分布式锁的代码放在事务外部,比如放在 controller 层
再次用 jmeter 多次压测,发现数据一致,问题解决。
问题二:
在事务的方法末尾发送mq, 消费者却消费不到这条数据,代码示例如下:
1 |
|
产生这样的原因和上述类似,事务的提交是要执行完整个事务方法的,事务还没提交就发送消息,消费端立即消费自然找不到这条数据。
解决方法:
- 发送延迟消息,如延迟3秒后消费
- 将发送消息的代码抽到事务方法外面,等整个事务提交后再发送mq
- Title: 记录项目中 spring 事务与分布式锁、mq消息发送使用不当的 bug
- Author: 薛定谔的汪
- Created at : 2019-11-11 14:48:33
- Updated at : 2026-03-18 15:58:26
- Link: https://www.zhengyk.cn/2019/11/11/project/tx-distributedLock/
- License: This work is licensed under CC BY-NC-SA 4.0.
Comments