开篇

 这篇文章的目的主要是讲解Fescar TC执行rollback的流程,目的是讲解清楚rollback流程中的一些步骤。

 遗憾的是因为rollback本身涉及Fescar的分支事务注册上报,如果事先不了解Fescar的分支事务,有些逻辑理解起来会有一些奇怪,对于branchSession本身还未了解,所以只能单独讲解rollback流程。

背景


说明:

  • 分支事务中数据的 本地锁 由本地事务管理,在分支事务 Phase1 结束时释放。
    同时,随着本地事务结束,连接 也得以释放。
  • 分支事务中数据的 全局锁 在事务协调器侧管理,在决议 Phase2 全局提交时,全局锁马上可以释放。只有在决议全局回滚的情况下,全局锁 才被持有至分支的 Phase2 结束。

这个设计,极大地减少了分支事务对资源(数据和连接)的锁定时间,给整体并发和吞吐的提升提供了基础。

这里需要重点指出的是:Phase1阶段的commit()操作是各个分支事务本地的事务操作。Phase2阶段的操作是全局的commit()和rollback()。TC-rollback流程指的就是Phase2阶段。

TC rollback流程介绍

rollback主流程

  • 1.根据transactionId查找begin阶段生成的GlobalSession对象。
  • 2.对GlobalSession对象进行close操作。
  • 3.TC通知所有RM(各分支事务的资源管理器)进行全局回滚操作(doGlobalRollback)。

TC rollback源码分析

public class DefaultCore implements Core {public GlobalStatus rollback(String xid) throws TransactionException {// 查找全局GlobalSession对象GlobalSession globalSession = SessionHolder.findGlobalSession(XID.getTransactionId(xid));if (globalSession == null) {return GlobalStatus.Finished;}GlobalStatus status = globalSession.getStatus();// Highlight: Firstly, close the session, // then no more branch can be registered.// 关闭全局的GlobalSession对象。globalSession.close(); if (status == GlobalStatus.Begin) {globalSession.changeStatus(GlobalStatus.Rollbacking);// 执行全局的rollback操作doGlobalRollback(globalSession, false);}return globalSession.getStatus();}
}

说明:

  • 查找全局的GlobalSession对象。
  • 关闭GlobalSession对象。
  • 执行全局的rollback操作。

GlobalSession关闭操作

public class GlobalSession implements SessionLifecycle, SessionStorable {public void close() throws TransactionException {if (active) {for (SessionLifecycleListener lifecycleListener : lifecycleListeners) {lifecycleListener.onClose(this);}}}public void onEnd(GlobalSession globalSession) throws TransactionException {removeGlobalSession(globalSession);}public void onStatusChange(GlobalSession globalSession, GlobalStatus status) throws TransactionException {updateGlobalSessionStatus(globalSession, status);}public void updateGlobalSessionStatus(GlobalSession session, GlobalStatus status) throws TransactionException {transactionStoreManager.writeSession(LogOperation.GLOBAL_UPDATE, session);}public void changeStatus(GlobalStatus status) throws TransactionException {for (SessionLifecycleListener lifecycleListener : lifecycleListeners) {lifecycleListener.onStatusChange(this, status);}this.status = status;}}
  • GlobalSession的close操作调用生命周期监听器lifecycleListener.onClose()。
  • lifecycleListener指的是DefaultSessionManager对象。

DefaultSessionManager操作

public class SessionHolder {public static GlobalSession findGlobalSession(Long transactionId) throws TransactionException {return getRootSessionManager().findGlobalSession(transactionId);}
}public class DefaultSessionManager extends AbstractSessionManager {}public abstract class AbstractSessionManager implements SessionManager, SessionLifecycleListener {protected Map<Long, GlobalSession> sessionMap = new ConcurrentHashMap<>();public GlobalSession findGlobalSession(Long transactionId) throws TransactionException {return sessionMap.get(transactionId);}public void onClose(GlobalSession globalSession) throws TransactionException {globalSession.setActive(false);}public void removeGlobalSession(GlobalSession session) throws TransactionException {transactionStoreManager.writeSession(LogOperation.GLOBAL_REMOVE, session);sessionMap.remove(session.getTransactionId());}
}

说明:

  • 生命周期监听器的onClose()设置GlobalSession对象的active状态为false。
  • findGlobalSession()方法从DefaultSessionManager返回GlobalSession对象。
public class DefaultCore implements Core {public void doGlobalRollback(GlobalSession globalSession, boolean retrying) throws TransactionException {for (BranchSession branchSession : globalSession.getReverseSortedBranches()) {BranchStatus currentBranchStatus = branchSession.getStatus();if (currentBranchStatus == BranchStatus.PhaseOne_Failed) {continue;}try {BranchStatus branchStatus = resourceManagerInbound.branchRollback(XID.generateXID(branchSession.getTransactionId()), branchSession.getBranchId(),branchSession.getResourceId(), branchSession.getApplicationData());switch (branchStatus) {case PhaseTwo_Rollbacked:globalSession.removeBranch(branchSession);LOGGER.error("Successfully rolled back branch " + branchSession);continue;case PhaseTwo_RollbackFailed_Unretryable:changeToRollbackFailedStatus(globalSession);globalSession.end();LOGGER.error("Failed to rollback global[" + globalSession.getTransactionId() + "] since branch[" + branchSession.getBranchId() + "] rollback failed");return;default:LOGGER.info("Failed to rollback branch " + branchSession);if (!retrying) {queueToRetryRollback(globalSession);}return;}} catch (Exception ex) {LOGGER.info("Exception rollbacking branch " + branchSession, ex);if (!retrying) {queueToRetryRollback(globalSession);if (ex instanceof TransactionException) {throw (TransactionException) ex;} else {throw new TransactionException(ex);}}}}if (globalSession.hasBranch()) {changeToRollbackFailedStatus(globalSession);} else {changeToRollbackedStatus(globalSession);}globalSession.end();}
}

说明:

  • doGlobalRollback()遍历GlobalSession当中所有的branchSession执行回滚操作。
  • 内部涉及到GlobalSession的状态迁移,这部分后面统一通过状态迁移实现。

Fescar TC-rollback流程相关推荐

  1. Fescar TC-commit流程

    开篇  这篇文章的目的主要是讲解Fescar TC执行commit的流程,目的是讲解清楚commit流程中的一些步骤.  遗憾的是因为commit本身Fescar的分支事务注册上报,如果事先不了解Fe ...

  2. Fescar TC-beigin流程

    开篇  这篇文章是用来讲解清楚TC(Transaction Coordinator:事务协调器)在处理TM发送过来的begin操作(事务开启操作).  核心逻辑包括GlobalSession对象的生成 ...

  3. Fescar 源码解析系列

    为什么80%的码农都做不了架构师?>>> Fescar example介绍 Fescar example解析 - TM流程 Fescar example解析 - GlobalTran ...

  4. GRS认证跟TC证有何区别

    [GRS认证跟TC证有何区别] GRS是全球回收利用规范,英文名字:GLOBALRecycledStandard(通称GRS验证)是全球化.自行化.完备的产品执行标准.供应链管理生产商操纵产品回收/再 ...

  5. 深入了解分布式事务组件 Seata :AT 模式(二)

    在前面一篇文章,我们介绍了阿里开源的分布式事务组件 Seata 的相关概念,重点介绍了 Seata 的 AT 模式.并通过一个 Spring-Cloud-JPA 的案例,演示了 AT 模式的使用入门. ...

  6. ecmascript_TC39及其对ECMAScript的贡献

    ecmascript by Parth Shandilya 通过Parth Shandilya TC39及其对ECMAScript的贡献 (TC39 and its contributions to ...

  7. 深度剖析Apache Shardingsphere对分布式事务的支持

    Apache ShardingSphere 是一套开源的分布式数据库中间件解决方案组成的生态圈,它由 JDBC.Proxy 和 Sidecar(规划中)这 3 款相互独立,却又能够混合部署配合使用的产 ...

  8. InnoDB 事务/锁/多版本分析?你了解多少?

    目录 • InnoDB事务 – 事务结构/功能 – XA事务/Group Commit – mini-transaction• InnoDB锁 – 锁结构/类型/功能 – 锁等待/死锁检测 – 自增序 ...

  9. 冰河联合猫大人又出版一本分布式事务领域的开山之作,这是要再次起飞了吗?

    大家好,我是冰河~~ 继出版<海量数据处理与大数据技术实战>和<MySQL技术大全:开发.优化与运维实战>之后,冰河联合猫大人一起推出了另一部硬核书籍<深入理解分布式事务 ...

最新文章

  1. 使用Apache cxf 和Spring在Tomcat下发布Webservice指南
  2. iOS进阶之架构设计MVVM模式实践(11)
  3. Objective-C学习—UIWebView的使用
  4. c语言折半查找法_C语言学习|选择法排序及折半查找法查找
  5. 中国研究的超级系统计算机,学习电脑 - Book3 - V1.30 - 超级系统恢复
  6. Android 滑动显示下一层界面
  7. Snchronize对象锁同步
  8. python内置类型_Python内置对象类型
  9. ASP.NET中 DataGrid简单自定义分页
  10. 聚焦数智技术助力乡村振兴 京东云为乡村振兴注入“数智”力量
  11. UVA10803 Thunder Mountain【Floyd算法】
  12. java utm坐标转经纬度,utm坐标和经纬度相互转换
  13. 平时常见的视频文件格式有哪些呢?
  14. SpringBoot的幕后推手是谁?
  15. 测试过程中遇到的问题总结
  16. Inc. magazine年度公司Evernote: 小小记事本如何风靡全球
  17. win7计算机自动关机设置在哪里设置方法,win7自动关机怎么设置
  18. 怎么保护地球生物多样性
  19. 【电影】-功夫巨星成龙电影全集版-原创独门专藏-
  20. 苹果4是android吗,呵呵!原来苹果手机有这么多缺点,你想换安卓吗?

热门文章

  1. IDEA 2019.2版本下载安装与PJ教程
  2. MyBatisPlus中常用条件构造器示例代码
  3. 第四期 SA 分析师认证名单正式公布!
  4. 今天,“场景赋能•驱动有数”,神策数据 2018 数据驱动大会在京成功举办
  5. 推荐一款好用的redis客户端工具
  6. Spring之使用注解实例化Bean并注入属性
  7. 11月17日学习内容整理:jquery文档处理,事件细讲,动画
  8. OpenSwitch操作系统成为Linux基金会官方项目
  9. mysql5.7二进制包安装
  10. C#技术分享【PDF转换成图片——13种方案】