前言
TODO
什么是分布式事务
基本定义
使用场景
随着互联网、金融等行业的快速发展,业务越来越复杂,一个完整的业务往往需要调用多个子业务或服务,随着业务的不断增多,涉及的服务及数据也越来越多越来越复杂。传统的系统难以支撑,出现了应用和数据库等的分布式系统。分布式系统又带来了数据一致性的问题,从而产生了分布式事务。
如何实现分布式事务
基于第一个强一致的思路,就有了基于数据库本身支持的协议,XA 分布式事务。XA 整体设计思路可以概括为,如何在现有事务模型上微调扩展,实现分布式事务。
X/Open,即现在的 open group,是一个独立的组织,主要负责制定各种行业技术标准。 X/Open 组织主要由各大知名公司或者厂商进行支持,这些组织不光遵循 X/Open 组织定义的行业技术标准,也参与到标准的制定。
XA 分布式协议
应用程序(Application Program ,简称AP):用于定义事务边界(即定义事务的开始和结束),并且在事务边界内对资源进行操作。
资源管理器(Resource Manager,简称 RM):如数据库、文件系统等,并提供访问资源的方式
事务管理器(Transaction Manager ,简称 TM):负责分配事务唯一标识,监控事务的执行进度,并负责事务的提交、回滚等。
XA 接口,如下的命令会在单机的 MySQL 数据库上执行。
xa_start :负责开启或者恢复一个事务分支
xa_end: 负责取消当前线程与事务分支的关联(表示 SQL 执行完成)
xa_prepare:询问 RM 是否准备好提交事务分支(判断当前数据库是否锁定资源,是否能够提交)
xa_commit:通知 RM 提交事务分支
xa_rollback: 通知 RM 回滚事务分支
xa_recover : 需要恢复的 XA 事务(查看当前的事务列表,即完成了 prepare 操作,但未提交或回滚)
思考:为什么 XA 事务又叫两阶段事务?
MySQL 数据库中,使用 SHOW ENGINES;
语句可以查看存储引擎是否支持 XA 事务,可以看到最常用的 InnoDB
存储引擎是支持 XA 事务的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| mysql> SHOW ENGINES; + | Engine | Support | Comment | Transactions | XA | Savepoints | + | ndbcluster | NO | Clustered, fault-tolerant tables | NULL | NULL | NULL | | FEDERATED | NO | Federated MySQL storage engine | NULL | NULL | NULL | | MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO | | InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES | | PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO | | MyISAM | YES | MyISAM storage engine | NO | NO | NO | | ndbinfo | NO | MySQL Cluster system information storage engine | NULL | NULL | NULL | | MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO | | BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO | | CSV | YES | CSV storage engine | NO | NO | NO | | ARCHIVE | YES | Archive storage engine | NO | NO | NO | + 11 rows in set (0.01 sec)
|
如下演示了在 MySQL 数据库上执行 XA 事务的过程,分布式事务通过相同的 xid 来关联,表示他们属于同一个分布式事务。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| mysql> XA START 'test'; Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO t_order_0 VALUES(1000, 1, 'OK', 1, 'TEST', NOW()); Query OK, 1 row affected, 1 warning (0.01 sec)
mysql> SELECT * FROM t_order_0; + | order_id | user_id | status | merchant_id | remark | creation_date | + | 1000 | 1 | OK | 1 | TEST | 2024-04-29 | + 1 row in set (0.01 sec)
mysql> XA END 'test'; Query OK, 0 rows affected (0.00 sec)
mysql> XA PREPARE 'test'; Query OK, 0 rows affected (0.00 sec)
mysql> XA RECOVER; + | formatID | gtrid_length | bqual_length | data | + | 1 | 4 | 0 | test | + 1 row in set (0.00 sec)
mysql> XA ROLLBACK 'test'; Query OK, 0 rows affected (0.01 sec)
mysql> SELECT * FROM t_order_0; Empty set (0.00 sec)
|
分布式事务常见方案
XA 分布式事务