本文共 741 字,大约阅读时间需要 2 分钟。
在微服务架构中难免会存在分布式事务的场景,但是实际来看,需要分布式事务的场景占比还是比较少的,因为绝大部分的接口都是get而不是set操作。可见,虽然分布式事务比较麻烦,但是也不要被这个东西吓到。
每一个存在分布式事务的操作因为业务逻辑都不一样,所以都需要单独设计实现。
场景:A 调用 B,且A和B都存在对数据库的set操作。
假设A和B都是自家公司开发的,所以,如果B出错,A不用回滚,找到B的负责人尽快修复。
下面开始设计A的实现流程。
1、在A中开启本地事务transaction,假设包含3个对数据库的操作act1, act2, act3;创建一个队列表queue_table,用来存储事务队列;queue_table表的insert操作和act1, act2, act3放在同一个事务中。
2、开启后台进程将表queue_table中的记录发送到MQ,此处不允许丢失,但允许重复投递,并修改记录的状态为已发送,此处要分表。
3、开启多进程消费MQ,请求B,做好幂等校验,遇到相同的请求直接丢弃;校验B的返回结果,如果返回失败,做一定次数的重试,再失败写入失败表。
注意是想
1、如果步骤1的性能有瓶颈,可以在步骤1之前加一层MQ。2、表queue_table的作用是直接投递MQ可能存在丢失或超时导致的数据不一致,并且queue_table中应该有uuid字段来保证消息幂等性。
3、如果B失败了,A实在必须回滚的话,比如跨行转账操作,那么A应该提供一个回滚接口,在操作3失败的时候调用A的回滚接口(此接口需要校验client ip,设置ip白名单),然后做好状态清理工作。
4、消息的幂等校验需要将uuid存储下来,为了提高检索效率,可以定期删除一段时间之前的记录。
转载地址:http://tdaui.baihongyu.com/