mysql8.0文档:https://dev.mysql.com/doc/refman/8.0/en/xa-statements.html。13.3.8.1 XA Transaction SQL Syntax章节讲述了Mysql对于XA事务的语法。
XA {START|BEGIN} xid [JOIN|RESUME] XA END xid [SUSPEND [FOR MIGRATE]] XA PREPARE xid XA COMMIT xid [ONE PHASE] XA ROLLBACK xid XA RECOVER [CONVERT XID]
首先,根据DTP(Distributed Transaction Processing: Reference Model)参考模型中,Mysql是作为资源管理器这一组件。所以Mysql也仅仅是作为XA规范中的一个组件而已,Mysql对于XA的支持,其实是提供了RMs与TM之间的接口交互支持。TM(Transaction manager)是一个事务的协调者,协调众多的事务参与者。明白了这一点以后,我们再来看Mysql中使用XA事务的语法,mysql官方文档中也有详细的描述,我们在下面列举一二,另外关于mysql支持XA是从什么版本开始,以及java驱动包什么版本支持XA,请见以下文档原文
Support for XA transactions is available for the
InnoDB
storage engine. The MySQL XA implementation is based on the X/Open CAE document Distributed Transaction Processing: The XA Specification. This document is published by The Open Group and available athttp://www.opengroup.org/public/pubs/catalog/c193.htm. Limitations of the current XA implementation are described in Section C.6, “Restrictions on XA Transactions”.
innodb存储引擎支持XA事务
Among the MySQL Connectors, MySQL Connector/J 5.0.0 and higher supports XA directly, by means of a class interface that handles the XA SQL statement interface for you.
5.0.0版本mysql连接驱动开始支持XA
XA事务命令都是XA开头的,xa start 和 xa begin 都可以开启一个xa事务,但是xa start 不支持join 、resume,这两个是什么,我暂时不了解,暂且不管,xa start 还需要跟一个xid,这个是事务的唯一标识,关于xid的构成,下面再详述,这里仅需要知道xid是一个事务的id标识即可。
xa end xid,即完成sql 操作后,让xa事务进入IDLE状态的命令,同样要指明xid,操作的是哪个XA事务,注意这里xa end并不是要结束xa事务,只是进入到IDLE状态,后续还有两阶段提交过程,prepare和commit;
xa prepare xid ,标识两阶段提交的第一个提交阶段,通知资源管理器RM做提交前的准备,防止数据丢失,之前讨论两阶段提交时已经讲了,这个阶段,mysql就会记录下这个事务的各种日志,防止丢失,即使宕机重启也能恢复。prepare结束就具备了这种恢复的能力,RM prepare回复TM,prepare成功后,RM会等TM的commit通知,而TM要等所有RM的成功消息,所有RM回复成功,TM就下发commit给所有RM;如果部分RM回复不成功,那么TM就下发rollback给所有RM回滚事务。
xa rollback xid就是回滚事务的指令,xa commit xid就是提交事务的指令,xa commit xid ONE PHASE 是明确知道RM只有一个的情况下,采用一阶段提交的方式,这种情况下就不需要prepare阶段了,xa end后即可xa commit xid ONE PHASE了。
xa recover ,是用来查看哪些xid已经完成prepare的,异常宕机情况下,xa recover也能列出宕机前哪些xa事务完成prepare,等待commit的。
xid: gtrid [, bqual [, formatID ]]
以上是xid的构成,gtrid全局事务id标识,然后bqual 事务分支标识,formatID是格式标识,具体什么用处暂时不明白。bqual和formatID都是可选,如果不给值时默认值分别为”和1.
gtrid 和 bqual 都必须是字符串类型,长度是64byte,formatID是无符号整型。
我们来看个实际例子
我建立了一个全局事务aaa,两个分支事务bbb和ccc。然后两个分支事务都进入了prepare,从分支事务ccc截图中xa recover可以看出。但是ccc回滚,bbb提交。最开始理解这块的时候,我认为既然一个全局事务,那么怎么能够一个回滚一个提交呢?后来仔细一想,这个过程应该是交给TM来统一的,mysql支持XA并不体现在控制全局事务下所有子事务一致提交,而是提供和TM交互的接口,由TM最终来控制,通知所有子事务提交,或都回滚,而不会通知部分提交、部分回滚。
编程的方式使用XA事务和以上方式类似,后面有空整理出代码