项目中如何使用消息队列实现分布式事务

项目中如何解决分布式事务的问题;
场景分析:
用户在购买商品成功后,微信或者支付宝会回调我们的接口,在一个service方法里面处理相应的业务逻辑;
其中包括了修改订单的状态为已支付(待发货),然后调用策略模块进行铜板分红的业务逻辑操作;
这个时候,赠送铜板(积分)是调用其他服务的,这时候涉及到了分布式事务的问题;
所以,我们需要设计一个解决分布式事务的方案,通过上面的业务场景的分析,赠送铜板是可以做成异步的,所以我们考虑了使用消息队列来解决分布式事务;

解决方案的步骤:
(1)更新订单的状态,然后发送一条消息队列到ActiveMQ
(2)策略服务监听这个消息对列,消费消息,然后赠送铜板

自己懒得画图,借用网上的图片

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

使用消息队列实现分布式事务,常见的哪些场景问题需要解决?
(1)如何保证业务一,操作数据库和发送消息到消息队列是在同一个事务里面执行的,如何保证这两者之间的一致性?
解决方案:建立一张事务表,此时,业务一的数据操作内容为:
1- 更新订单的状态为已支付
2- 给事件表插入一条记录
这个时候是对同一个数据库的表的操作,因此可以用数据库的事务进行保证;
另外,启动一个定时程序,定时扫描事务表,发现这张事务表,里面状态为unfinished的事件,就进行凤封装为消息,然后发送到消息队列中,修改状态finished。
因此保证了操作数据和发送消息到消息队列的操作是具备原子性的;

 

(2)消费消息队列的数据,如何保证幂等性的问题!
上面的情况是解决了操作数据和发送消息都是在同一个事务里面执行的,保证了一致性。但是他确确实实存在幂等性的问题
注意了,这一版还存在一个幂等性问题!
仔细看,定时程序做了如下三个操作
(1)定时扫描事务表,发现一个状态为’UNFINISHED’的事件
(2)将事件信息,封装为消息,发送到消息中间件
(3)将事件状态改为’FINISHED’

 

OK,假设在步骤(2)的时候,发送完消息体,还未执行步骤(3),定时程序阵亡了!然后重启定时程序,发现刚那个事务的状态依然为’UNFINISHED’,因此重新发送。这样,就会出现重复消费问题。因此,幂等性也是需要保证的!
在消费端,也维护一个带主键的表,可以选择txId(事务ID)为主键,通过数据库的主键保证幂等性。

Add a Comment

电子邮件地址不会被公开。 必填项已用*标注