• 分布式事务解决方案汇总


    2阶段(2PC)提交方案:
     
    实现原理:基于XA规范搞的一套分布式事务的理论,也可以叫做一套规范,或者是协议。
    (1)准备阶段(Prepare phase):事务管理器给每个参与者发送prepare消息,每个数据库参与者在本地执行事务,并写本地的Undo/Redo,此时事务没有提交。
    (2)提交阶段(Commit phase):如果事务管理器接收了参与者执行失败或者超时消息时,直接给每个参与者发送回滚消息,
    否则发送提交消息;参与者根据事务管理器的指令执行提交或者回滚操作,并释放事务处理过程中使用的锁资源。
     
    代码实现参考:
    public static void main(String[] args) throws SQLException, XAException {
    
            // 获得资源管理器操作接口实例 RM1
            Connection conn1 = DriverManager.getConnection("jdbc:mysql://localhost:3306/dev", "root", "123456");
            XAConnection xaConn1 = new MysqlXAConnection((JdbcConnection) conn1, true);
            XAResource db1 = xaConn1.getXAResource();
    
            // 获得资源管理器操作接口实例 RM2
            Connection conn2 = DriverManager.getConnection("jdbc:mysql://localhost:3306/db2", "root", "123456");
            XAConnection xaConn2 = new MysqlXAConnection((JdbcConnection) conn2, true);
            XAResource db2 = xaConn2.getXAResource();
            // 应用程序 请求事务管理器 执行一个分布式事务,事务管理器 生成全局事务id
            byte[] gtrid = "g12345".getBytes();
            Xid id1 = new MysqlXid(gtrid, "b00001".getBytes(), 1); // 事务管理器生成 db1上的事务分支id
            Xid id2 = new MysqlXid(gtrid, "b00002".getBytes(), 1); // 事务管理器生成db2上的事务分支id
    
            try {
                // 执行db1上的事务分支
                db1.start(id1, XAResource.TMNOFLAGS);
                PreparedStatement ps1 = conn1.prepareStatement("INSERT into user_info(user_id, user_name) VALUES ('5', 'test')");
                ps1.execute();
                db1.end(id1, XAResource.TMSUCCESS);
    
                // 执行db2上的事务分支
                db2.start(id2, XAResource.TMNOFLAGS);
                PreparedStatement ps2 = conn2.prepareStatement("INSERT into accounts(userId, accountNumber) VALUES (2, 10000)");
                ps2.execute();
                db2.end(id2, XAResource.TMSUCCESS);
    
                // 准备两阶段提交  phase1:询问所有的RM 准备提交事务分支
                int rm1Prepare = db1.prepare(id1);
                int rm2Prepare = db2.prepare(id2);
    
                //提交所有事务分支, TM判断有2个事务分支,所以不能优化为一阶段提交
                if (rm1Prepare == XAResource.XA_OK && rm2Prepare == XAResource.XA_OK) {
                    db1.commit(id1, false);
                    db2.commit(id2, false);
                    System.out.println("成功");
                } else {
                    System.out.println("如果有事务分支没有成功,则回滚");
                    db1.rollback(id1);
                    db2.rollback(id2);
                }
                int a = 1/0;
            } catch (Exception e) {
                e.printStackTrace();
                db1.rollback(id1);
                db2.rollback(id2);
                System.out.println("异常error");
            }
        }
    1.最好pom引入开源的分布式事务管理器,如Atomikos作为本地事务管理器。如:Spring Boot集成atomikos快速入门Demo
    2.在分布式环境中,每个服务配置 Atomikos 作为本地事务管理器,但是全局事务的管理和协调是由一个独立的分布式事务协调器(DTC)来完成。
    3.在分布式环境中,独立的分布式事务协调器(DTC)通常是一个单独的服务或组件。通常情况下,项目除了引入 Atomikos 作为本地事务管理器之外,还需要考虑如何部署和配置这个分布式事务协调器。
    4.在分布式环境中,确保分布式事务的一致性和可靠性需要配合使用本地事务管理器(如 Atomikos)和一个独立的分布式事务协调器(DTC)。
     
     
  • 相关阅读:
    Water 2.5.8 发布,一站式服务治理平台
    一些关于完整小程序项目的优秀开源
    windows Oracle Database 19c 卸载教程
    【C++初阶7-string】真方便,真舒服
    每天5分钟复习OpenStack(七)内存虚拟化
    【继承和多态】
    【Qt】Qt下配置OpenCV
    2024年区块链链游即将迎来大爆发
    MySQL实战基础知识入门(13):数据类型
    服务注册Eureka
  • 原文地址:https://www.cnblogs.com/lgg20/p/18245990