seata分布式事务的解决方案

seata:Simple Extensible Autonomous Transaction Architecture

官方:https://github.com/seata/seata

中文wiki:https://github.com/seata/seata

 注意:数据库表的主键问题!!!!!如果要使用seata,那么对应的表必须要有主键存在。

结构

Seata有3个基本组件:

  • Transaction Coordinator(TC):事务协调器(独立运行的应用程序),维护全局事务的运行状态,负责协调并驱动全局事务的提交或回滚。

  • Transaction Manager(TM):事务管理器,控制全局事务的边界,负责开启一个全局事务,并最终发起全局提交或全局回滚的决议。

  • Resource Manager(RM):资源管理器,控制分支事务,负责分支注册、状态汇报,并接收事务协调器的指令,驱动分支(本地)事务的提交和回滚。

全局事务与分支事务:

a Distributed Transaction is a Global Transaction which is made up with a batch of Branch Transaction, and normally Branch Transaction is just Local Transaction.

 

Seata管理分布式事务的典型生命周期:

  • TM 向 TC 申请开启一个全局事务,全局事务创建成功并生成一个全局唯一的 XID。

  • XID 在微服务调用链路的上下文中传播。

  • RM 向 TC 注册分支事务,将其纳入 XID 对应全局事务的管辖。

  • TM 向 TC 发起针对 XID 的全局提交或回滚决议。

  • TC 调度 XID 下管辖的全部分支事务完成提交或回滚请求。

至此,seata的协议机制总体上看与 XA 是一致的。但是是有差别的:  

XA 方案的 RM 实际上是在数据库层,RM 本质上就是数据库自身(通过提供支持 XA 的驱动程序来供应用使用)。

而 Fescar 的 RM 是以二方包的形式作为中间件层部署在应用程序这一侧的,不依赖于数据库本身对协议的支持,当然也不需要数据库支持 XA 协议。这点对于微服务化的架构来说是非常重要的:应用层不需要为本地事务和分布式事务两类不同场景来适配两套不同的数据库驱动。

这个设计,剥离了分布式事务方案对数据库在 协议支持 上的要求。

快速入门

springCloud整合seata:https://github.com/seata/seata-samples/tree/master/springcloud-jpa-seata

官方提供了案例工程(README.md有详细的执行流程和需要的工具,编译工具IDEA就行):

案例工程结构如下:

 

测试:

完成后可以看到数据库中 account_tblid为1的money会减少 5,order_tbl中会新增一条记录,storage_tblid为1的count字段减少 1

  • 发生异常事务回滚
http://127.0.0.1:8084/purchase/rollback

此时 account-service 会抛出异常,发生回滚,待完成后数据库中的数据没有发生变化,回滚成功

具体流程自己打断点调试。

总结流程:浏览器访问/rollback --> business-service的Controller让1002账户买东西 --> order-service创建订单,并远程调用1002的账户信息扣款 --> account-service扣款,并在最后制造一个运行时异常。

导致:account-service异常 --> 调用方order-service异常 --> 调用方business-service异常。

但是:storage-service执行正常。

由于business-service使用了分布式事务,所以storage-service数据回滚。最后都没有数据更新

.

为什么发生异常了,数据库中的数据没有发生变化,即所有微服务在某个微服务发生异常时回滚了。

@GlobalTransactional注解,声明了一个全局事务,而其他被调用的微服务中的Service中的@Transactional注解声明的是一个分支事务。

将需要的配置弄好,就可以使用这两个注解实现分布式的事务了

 

发布了126 篇原创文章 · 获赞 6 · 访问量 3728

猜你喜欢

转载自blog.csdn.net/qq_40244391/article/details/104197282