先说分布式事物方案+自己项目实际用到的。
自己项目中的场景:大致托管划款指令授权的时候最终流程落地的时候会推一个划款指令给外部系统,然后会给自己本地表里也插一个划款指令。这两个操作要求原子性其中有一个失败就需要回滚事物。
分布式事物
分布式事物规范,定义了分布式事物模型。
四个角色
事物管理器(TM协调者)
资源管理器(RM):上报版本状态给TM,理解为不同数据库
应用程序AP
通信资源管理器CRM
两阶段提交:
第一阶段:每个参与者执行本地事物但是不提交,进入ready状态
第二阶段:当协调者确认每个参与者都ready后,通知参与者提交如果有其中一个失败,者发送rollback,所有参与者一起回滚。
会存在的问题:
单点故障,整个系统不可用
数据不一致:第二阶段,由于网络问题有的没有收到可能导致数据不一致。
三阶段提交:对二阶的优化,例如事物管理器如果挂了,资源管理器会自己进行commit.并且它在第一阶段的时候会先去判断数据库环境是否正常。
实现:JTA是java对XA规范的实现,对应JDBC的事物
缺陷:一般每个服务如果操作多个库实际上是不规范的,还有基于数据库实现分布式事物性能不行。
try,检查资源(例如100都没有就不发起)
confirm,业务的确认
cancel,回滚
(补偿事物,和数据库没有关系完全从业务层面处理)
例如AB两个系统,A系统先插入自己的业务表,然后再插入一张消息表,两张表插入成功代表A事物执行成功。然后A系统会发消息到MQ。然后B系统会先插自己的消息表(为了防止重复消费,消费幂等,例如消息表里有消息的唯一键,那就先校验消息表,已消费的消息就回滚),然后B系统插入自己的业务表成功之后调用A的接口去更新消息状态。
A调B,A在事物提交的时候发送prepared消息到中间件(A未提交前消息对B不可见)
发送成功后执行本地事物:成功commit,消息中间件消息下发至消费端。如失败回滚,消息中间件将这条prepare消息删除
B收到消息进行消费,如果消费失败,不断重试
可以允许少数分布式事物失败,一般用于事物要求不是特别严格的,例如记录日志这样的操作