持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第9天,点击查看活动详情
是基于两阶段提交改进实现的
分别是Lock(锁定单元事务)、 Confirm(确定事务)、Notify(通知事务)
它是对两阶段提交进行改进后实现的,主要也分为两个大步骤,一阶段为锁定资源阶段,二阶段为通知阶段,提交或者回滚操作
锁定资源阶段,第一步是创建事务组,也就是调用TxManager创建事务组对象,然后拿到事务标示GroupID;第二步就是执行业务;当业务中设计请求其他服务的时候,调用其他服务B,服务B执行业务,然后加入事务组,也就是把事务信息通知给TXManager,成功后返回响应;如此循环往复,直到调用完最后一个微服务后,就进入第二阶段,也就是通知阶段,就是发起方将执行结果状态通知给TXManager,TXManager将根据事务最终状态和事务组的信息来通知响应的参与模块提交或者回滚事务,并将结果返回给事务发起方,最后关闭连接。
调用
我按照官网的流程也做过LCN关于订单系统和支付系统的小demo,熟悉它的搭建流程。
首先就是搭建LCN,在pom文件中导入jar包,然后再application.properties中建立相关的访问和连接,在启动程序中写个注解也就是@EnableTransactionManagerServer,启动,就搭建完成了
然后在订单业务中导入pom文件,在yml中添加LCN地址,然后连接数据库,dao中添加注解@Mapper
写一个controller,添加注解@LcnTransaction
写一个微服务最普通的调用,
同理写支付订单,
在order和pay的lcnPayApplication启动类中加注解主函数外部加@EnableDistributedTransaction
启动eureka,就可以了
问题
1、因为网断或者服务挂了,等不到第二阶段的请求怎么办?
TM做一个标识,当前某个事务,请求通知不到,需要补偿。做记录(通知的具体事项,或者需要执行SQL的操作,因为有可能是服务挂了,下次起来后,得知道我让他执行什么事儿,所以需要记录执行SQL的操作)
其中Redis存事务组和补偿信息(为什么存缓存?存DB读取的是磁盘,存缓存读取的是内存,内存和磁盘速度相差10W倍,所以一般中间件都是用Redis)
特点
LCN模式是通过代理Connection的方式实现对本地事务的操作,然后在由TxManager统一协调控制事务。当本地事务提交回滚或者关闭连接时将会执行假操作,该代理的连接将由LCN连接池管理。
- 该模式对代码的嵌入性为低。
- 该模式仅限于本地存在连接对象且可通过连接对象控制事务的模块。
- 该模式下的事务提交与回滚是由本地事务方控制,对于数据一致性上有较高的保障。
- 该模式缺陷在于依赖于连接代理服务,事务的发起方与参与方要一起连接与释放,较耗性能增加了连接占用的时间。