java 分布式事务

一:分布式事务-跨库事务(一个服务中操作多个数据源)

1,XA/JTA(2PC)两阶段提交

第一阶段:预提交(如:1.执行完sql,还没有commit 2.锁定资源 3.校验数据库、缓存中间件是否正常)

第二阶段:真正的提交

使用框架Atomikos(相当于一个全局的事务管理器)

注:这个方案,我们很少使用,一般来说某个系统内部如果出现跨多个库的操作,是不合规的,现在的微服务,一个大的系统分成若干个服务,一般来说,我们的规定,是要求每个服务只能操作自己对应的一个数据库;如果你要操作别的服务对应的库,则不允许直连,如果随便交叉访问,若干个服务的统一治理性大大下降,则会经常出现类似数据被别人改错,自己的库被别人写挂。如果你要操作别的服务的数据库,必须是通过调用别的服务的接口来实现,绝对不允许你交叉访问别的数据库。

二:分布式事务-微服务(每个服务持有一个事务)

1.TCC(Try-Confirm-Cancle)两阶段补偿型方案

第一阶段:预留资源(try)

第二阶段:确认资源(confirm/cancle)

注:适合场景:一致性要求很高,一般跟钱打交道,如支付、交易相关场景,我们会用tcc,严格保证分布式事务要么全部成功,要么全部回滚,严格保证资金的正确性。

三:本地消息表

大致意思

1.A系统在自己本地一个事务里操作同时插入一条数据到消息表,接着A系统将这个消息发送到MQ中去。

2.B系统接收到消息之后,在一个事务里,往自己本地消息表里插入一条数据,同时执行其他的业务,如果这个消息已经被处理过了(指的是A系统发到MQ中的消息,使用业务唯一键来判断来保证幂等性,如订单id),那么这个事务会回滚,这样保证不会重复处理消息。

3.B系统执行成功之后,就会更新自己本地消息表的状态以及A系统消息表的状态

4.如果B系统处理失败了,那么就不更新消息表状态,那么此时A系统会定时扫描自己的消息表,如果有没处理的消息,会再次发送到MQ中,让B再次处理。

5.这个方案保证了最终一致性,哪怕B事务失败了,但是A会不断重发消息,直到B那边成功为止。

注:这个方案会严重依赖数据库消息表来管理事务,不适合高并发场景,所以一般用的不多。

四:最终一致性

使用RocketMQ(3.2.6之前的版本),属于本地消息表的升级表,因把消息的重试的机制都集成到MQ服务中。

总结:除了关于资金使用TCC来保证强一致性,其余都可以使用RocketMQ来实现

 

 

 

 

你可能感兴趣的:(Spring,Cloud,分布式,java,后端)