业务场景:
在做促销中心时需要一个接口,客户领取大通宝!本地数据库更新领取人和领取状态,然后在用户中心记录余额增加(此处有并发,使用的是分布式锁,前文有介绍)
问题分析:
由于本地库和用户中心库是在不同数据库,涉及到事务问题,spring的事务只能控制当前库回滚,不能控制远程库!
原始操作:
1.先调用户中心余额增加,本地记录领取人,这是同步的,根据返回结果来判断是否本地记录领取人,此时用户中心出现异常,不记录领取人!但是用户中心余额增加成功,本地出现异常进行回滚,这时不能控制用户中心余额回滚!
解决方案:
使用定时任务和消息队列来解决,实现100%正确
1.修改当前记录的领取人和状态(已领取),本地记录领取信息到定时任务表
2.定时任务发消息
3.用户中心监听加余额消息(记录本地消息表和增加余额,余额增加成功向消息队列发送余额增加成功的消息)
4.本地服务监听余额增加成功消息(删除本地定时任务消息)
新问题及解决方案:
1.
问题:会出现余额增加多次的情况,并不能保证定时任务只发送一次!
解决:用户中心也记录了消息表,根据消息id判断,只要消息id之前有就不再增加余额了
2.
问题:用户中心余额增加了未发送余额增加消息!
解决:这边本地有定时任务表,只要这个表的数据没删就会重新请求用户中心服务
3.
问题:用户中心消息表写成功但是未增加余额!
解决:在同一个事务中,不会出现这个问题!(本地消息表和记录领取信息也是类似)