深入解析:MySQL对分布式事务 XA Transactions 的支持
导读:MySQL对分布式事务(XA Transactions)进行了很好的支持,我们看看它是怎么做的,并实战验证其提供的分布式事务控制语句效果。
-
X/Open是一个独立的、全球性的开放系统组织,由世界上最大的信息系统供应商、用户组织和软件公司支持。其使命是通过开放系统的实际实施,为用户带来更大的计算价值。 -
X/Open CAE规范,即X/Open Common Applications Environment,这个环境覆盖了高于硬件级别的,支持开放系统所需的一组标准。它提供了应用程序的可移植性和互操作性。
-
资源管理器(RM)用于提供通向事务资源的途径。数据库服务器是一种资源管理器,该管理器必须可以提交或者回滚由RM管理的事务。 -
事务管理器(TM)用于协调作为一个分布式事务一部分的事务。TM与管理每个事务的RMs进行通信。在一个分布式事务中,各个单个事务均是分布式事务的“分支事务”。分布式事务和各分支通过一种命名方法进行标识。
-
在第一阶段,所有的分支被预备好。即它们被TM告知要准备提交。 -
在第二阶段,TM告知RMs是否要提交或回滚。如果在预备分支时,所有的分值指示它们将能够提交,则所有的分支被告知要提交。如果在预备时,有任何分支指示它将不能提交,则所有分支被告知回滚。
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]
xid: gtrid
-
gtrid是全局事务标识符。 -
bqual是分支限定符,默认值是’’,对于分布式事务中的每个分支事务,bqual值必须是唯一的。 -
formatID是标识gtrid和bqual值使用的格式,默认值为1。
root@database-one 21:19: [(none)]> create database cash_gftest default charset utf8;
Query OK, 1 row affected (0.02 sec)
root@database-one 21:25: [(none)]> use cash_gftest;
Database changed
root@database-one 21:25: [cash_gftest]> create table cash_account(name varchar(10),balance decimal(10,2)) engine=innodb;
Query OK, 0 rows affected (0.05 sec)
root@database-one 21:25: [cash_gftest]> insert into cash_account values('郭佳',10000),('刘强',8000),('肖杰',22000);
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
root@database-one 21:29: [cash_gftest]> create database financing_gftest default charset utf8;
Query OK, 1 row affected (0.00 sec)
root@database-one 21:29: [cash_gftest]> use financing_gftest
Database changed
root@database-one 21:29: [financing_gftest]> create table financing_account(name varchar(10),balance decimal(10,2)) engine=innodb;
Query OK, 0 rows affected (0.08 sec)
root@database-one 21:30: [financing_gftest]> insert into financing_account values('郭佳',0),('刘强',0),('肖杰',0);
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
root@database-one 21:30: [financing_gftest]> select * from financing_gftest.financing_account;
+--------+---------+
| name | balance |
+--------+---------+
| 郭佳 | 0.00 |
| 刘强 | 0.00 |
| 肖杰 | 0.00 |
+--------+---------+
3 rows in set (0.00 sec)
root@database-one 21:31: [financing_gftest]> select * from cash_gftest.cash_account;
+--------+----------+
| name | balance |
+--------+----------+
| 郭佳 | 10000.00 |
| 刘强 | 8000.00 |
| 肖杰 | 22000.00 |
+--------+----------+
3 rows in set (0.00 sec)
root@database-one 21:36: [(none)]> prompt \u@database-one \R:\m:\s [\d] session1>
PROMPT set to '\u@database-one \R:\m:\s [\d] session1>'
root@database-one 21:36:33 [(none)] session1>use cash_gftest;
Database changed
root@database-one 21:36:49 [cash_gftest] session1>select * from cash_account;
+--------+----------+
| name | balance |
+--------+----------+
| 郭佳 | 10000.00 |
| 刘强 | 8000.00 |
| 肖杰 | 22000.00 |
+--------+----------+
3 rows in set (0.01 sec)
root@database-one 21:38: [(none)]> prompt \u@database-one \R:\m:\s [\d] session2>
PROMPT set to '\u@database-one \R:\m:\s [\d] session2>'
root@database-one 21:38:38 [(none)] session2>use financing_gftest;
Database changed
root@database-one 21:38:50 [financing_gftest] session2>select * from financing_account;
+--------+---------+
| name | balance |
+--------+---------+
| 郭佳 | 0.00 |
| 刘强 | 0.00 |
| 肖杰 | 0.00 |
+--------+---------+
3 rows in set (0.00 sec)
root@database-one 21:45:09 [cash_gftest] session1>xa start 'transfer_of_account','cash';
Query OK, 0 rows affected (0.01 sec)
root@database-one 21:45:43 [cash_gftest] session1>update cash_account set balance=balance-3000 where name='肖杰';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
root@database-one 21:46:50 [cash_gftest] session1>xa end 'transfer_of_account','cash';
Query OK, 0 rows affected (0.01 sec)
root@database-one 21:48:17 [cash_gftest] session1>xa prepare 'transfer_of_account','cash';
Query OK, 0 rows affected (0.00 sec)
root@database-one 21:54:24 [financing_gftest] session2>xa start 'transfer_of_account','financing';
Query OK, 0 rows affected (0.00 sec)
root@database-one 21:54:51 [financing_gftest] session2>update financing_account set balance=balance+3000 where name='肖杰';
Query OK, 1 row affected (0.06 sec)
Rows matched: 1 Changed: 1 Warnings: 0
root@database-one 21:55:28 [financing_gftest] session2>xa end 'transfer_of_account','financing';
Query OK, 0 rows affected (0.02 sec)
root@database-one 21:56:03 [financing_gftest] session2>xa prepare 'transfer_of_account','financing';
Query OK, 0 rows affected (0.02 sec)
root@database-one 22:04:50 [cash_gftest] session1>xa recover;
+----------+--------------+--------------+------------------------------+
| formatID | gtrid_length | bqual_length | data |
+----------+--------------+--------------+------------------------------+
| 1 | 19 | 4 | transfer_of_accountcash |
| 1 | 19 | 9 | transfer_of_accountfinancing |
+----------+--------------+--------------+------------------------------+
2 rows in set (0.00 sec)
root@database-one 22:06:05 [financing_gftest] session2>xa recover;
+----------+--------------+--------------+------------------------------+
| formatID | gtrid_length | bqual_length | data |
+----------+--------------+--------------+------------------------------+
| 1 | 19 | 4 | transfer_of_accountcash |
| 1 | 19 | 9 | transfer_of_accountfinancing |
+----------+--------------+--------------+------------------------------+
2 rows in set (0.01 sec)
两个会话都能看到两个分支事务的信息,这是因为这两个库是在同一个MySQL服务中,如果是位于不同的MySQL服务中,将只能看到各自的分支事务信息。
root@database-one 22:12:43 [cash_gftest] session1>xa commit 'transfer_of_account','cash';
Query OK, 0 rows affected (0.01 sec)
root@database-one 22:13:50 [financing_gftest] session2>xa commit 'transfer_of_account','financing';
Query OK, 0 rows affected (0.00 sec)
推荐阅读:
数据和云
ID:OraNews
如有收获,请划至底部,点击“在看”,谢谢!
点击下图查看更多 ↓
云和恩墨大讲堂 | 一个分享交流的地方
请备注:云和恩墨大讲堂