XA是由X/Open组织提出的分布式事务的规范。由于太耗费性能,在实际应用中不大会使用。
1. 组成
- TM:一个事务管理器,创建分布式事务并协调分布式事务中的各个子事务的执行和状态,子事务就是指在 RM 上执行的具体操作。
- RM:多个资源管理器,事务的参与者,通常是指数据库。一个分布式事务通常有多个资源管理器
2. 2PC 二阶段提交
提交分为两个阶段:prepare(准备阶段)和commit(提交阶段)
1.准备阶段:事务管理器给每个参与者发布Prepare消息,每个服务参与者在本地执行事务,并写在Undo/Redo日志,此时事务没有提交。(Undo日志记录修改前数据用于回滚,Redo记录修改后数据用于提交事务后写入数据文件)
2.提交阶段:如果事务管理器收到了参与者的执行失败或者超时消息时,直接给每个参与者进行回滚,否则发送提交消息。注意:必须在最后阶段释放锁资源
使用2pc 完成分布式事务有这两种情况:
- 理想情况下:若所有的参与者都返回同意的消息,那么事务管理器就知道所有的参与者都已经准备好了,协调者就会向所有的参与者发回一个提交的消息,参与者在收到提交消息之后,会将本地事务进行提交,并且释放占用的资源,在处理完成之后,会返回一个完成的消息,分布式事务也就完成了。
- 异常情况下: 假如其中的一个参与者出现了异常,这时候会向事务管理器发送终止消息,然后事务管理器收到回滚请求后,会将所有的操作进行撤销,恢复到事务启动前的状态,分布式事务执行失败。
看起来是没有问题,但是它肯定存在很多缺点:
- 1、事务管理器挂掉了怎么办?整个分布式就没办法继续执行
- 2、假设某个参与者的提交消息因为网络中断了,请求没有到达,这个也没有发送异常消息回来,那么事务就执行失败了。
针对 2pc 的缺点,提出了三阶段提交,它在协调者和参与者中都引入了超时机制,并且把两阶段提交协议的第一个阶段分为两步:询问,然后再锁资源,最后真正提交。
- 1、预备阶段:协调者向参与者发送 commit 请求,参与则如果可用就返回 yes、或no 。
- 2、预提交阶段:发送请求后执行事务操作,将信息记录到事务日志中。如果某个协调者没有执行,就中断事务
- 3、真正提交:该过程来进行最终的事务执行或中断事务操作。
但是 2pc 和 3pc 都无法彻底解决分布式的一致性问题。
保证数据的强一致性。commit阶段出现问题,事务出现不一致问题,需要人工处理。效率低下,性能与事务相差10倍。
Mysql5.7以上都支持XA协议
Mysql Connector/j 5.0以上支持XA协议。
java系统中,数据源采用 Atomikos ,在事务中充当事务管理器作用