分布式事务解决方案汇总

2阶段(2PC)提交方案:
实现原理:基于XA规范搞的一套分布式事务的理论,也可以叫做一套规范,或者是协议。
(1)准备阶段(Prepare phase):事务管理器给每个参与者发送prepare消息,每个数据库参与者在本地执行事务,并写本地的Undo/Redo,此时事务没有提交。
(2)提交阶段(Commit phase):如果事务管理器接收了参与者执行失败或者超时消息时,直接给每个参与者发送回滚消息,
否则发送提交消息;参与者根据事务管理器的指令执行提交或者回滚操作,并释放事务处理过程中使用的锁资源。
代码实现参考:

public static void main(String[] args) throws SQLException, XAException {
        boolean logXaCommands = true;
        // 获得资源管理器操作接口实例 RM1
        Connection conn1 = DriverManager.getConnection("jdbc:mysql://localhost:3306/dev", "root", "123456");
        XAConnection xaConn1 = new MysqlXAConnection((JdbcConnection) conn1, logXaCommands);
        XAResource db1 = xaConn1.getXAResource();

        // 获得资源管理器操作接口实例 RM2
        Connection conn2 = DriverManager.getConnection("jdbc:mysql://localhost:3306/db2", "root", "123456");
        XAConnection xaConn2 = new MysqlXAConnection((JdbcConnection) conn2, logXaCommands);
        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)。