Seata 客户端需要同时启动 TM 和 RM 吗?
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>
在分析启动部分源码时,我发现 GlobalTransactionScanner 会同时启动 RM 和 TM client,但根据 Seata 的设计来看,TM 负责全局事务的操作,如果一个服务中不需要开启全局事务,此时是不需要启动 TM client的,也就是说项目中如果没有全局事务注解,此时是不是就不需要初始化 TM client 了,因为不是每个微服务,都需要 GlobalTransactional,它此时仅仅作为一个 RM client 而已。
于是我着手将 GlobalTransactionScanner 稍微更改了初始化的规则,由于之前 GlobalTransactionScanner 调用 初始化方法是在 InitializingBean 中的 afterPropertiesSet() 方法中进行,afterPropertySet() 仅仅是当前 bean 初始化后被调用,此时无法得知当前 Spring 容器是否有全局事务注解。
因此我去掉了 InitializingBean,改成了是实现 ApplicationListener,在实例化 bean 的过程中检查是否有 GlobalTransactional 注解的存在,最后在 Spring 容器初始化完成之后再调用 RM 和 TM client 初始化方法,这时候就可以根据项目是否有用到全局事务注解来决定是否启动 TM client 了。
这里附上 PR 地址:https://github.com/seata/seata/pull/1936
随后在 pr 中讨论中得知,目前 Seata 的设计是只有在发起方的 TM 才可以发起 GlobalRollbackRequest,RM 只能发送 BranchReport(false) 上报分支状态个 TC 服务端,无法直接发送 GlobalRollbackRequest 进行全局回滚操作。具体的交互逻辑如下:
那么根据上面的设计模型,自然可以按需启动 TM client 了。
但是 Seata 后面的优化迭代中,还需要考虑的一点是:
当 Provider 服务出现异常时,是否可以直接由 Provider 的 TM client 发起全局回滚?这也就意味着可以缩短分布式事务的周期时间,尽快释放全局锁让其他数据冲突的事务尽早的获取到锁执行。
也就是说在一个全局事务当中,只要有一个 RM client 执行本地事务失败了,直接当前服务的 TM client 发起全局事务回滚,不必要等待发起方的 TM 发起的决议回滚通知了。如果要实现这个优化,那么就需要每个服务都需要同时启动 TM client 和 RM client。
更多精彩文章请关注作者维护的公众号「后端进阶」,这是一个专注后端相关技术的公众号。
关注公众号并回复「后端」免费领取后端相关电子书籍。
欢迎分享,转载请保留出处。
- service启动activity同时需要得到activity里的某个对象实现方法
- ASP.NET MVC无法在Web 服务器上启动调试.远程服务器返回错误:(400);System.Data.OracleClient 需要Oracle 客户端软件 version...或更高版本
- 多个tomcat同时启动时需要修改的3个端口
- 需要同时启动多个tomcat的配置
- 【备忘】指定eclipse启动时需要的jdk
- SpringCloud eureka客户端启动过程解析
- pb903+sqlserver2000开发得程序,客户端需要得dll
- 如何在一台服务器上同时启动多个tomcat进程
- 如何在同一系统里同时启动多个Tomcat
- Tomcat 启动 需要初始化元素 Listener
- 为什么计算机网络同时需要IP地址和MAC地址?
- Socket编程服务器和客户端(多个客户端可以同时连接一个服务器的同一端口)
- RESIN4在一台机器上同时启动多个
- 文件系统的缺陷----导致数据库系统--同时也是数据库中需要避免的
- ubuntu16.04怎么关掉图形界面启动(需要用root权限)
- 如何限制同一客户端登录的用户数量以及禁止同一用户同时在不同客户端登录
- 利用域控设置启动脚本统一更改客户端administrator密码和添加客户端本地管理员账号
- TCP实现ECHO程序(服务端同时处理多个客户端的响应)
- kafka1.0.0安装启动和客户端基本使用
- ASP.NET State Service (ASP.NET 状态服务)已启动,并且客户端端口与服务器端口相同。