XA规范
在谈到 XA 规范之前,必须首先了解分布式事务处理( Distributed Transaction Processing , DTP )的概念。 Transaction ,即事务,又称之为交易,指一个程序或程序段,在一个或多个资源如数据库或文件上为完成某些功能的执行过程的集合。
分布式事务处理是指一个事务可能涉及多个数据库操作,分布式事务处理的关键是必须有一种方法可以知道事务在任何地方所做的所有动作,提交或回滚事务的决定必须产生统一的结果(全部提交或全部回滚)。
X/Open 组织(即现在的 Open Group )定义了分布式事务处理模型。 X/Open DTP 模型( 1994 )包括应用程序( AP )、事务管理器( TM )、资源管理器( RM )、通信资源管理器( CRM )四部分。
一般常见的事务管理器( TM )是交易中间件,常见的资源管理器( RM )是数据库,常见的通信资源管理器( CRM )是消息中间件。
通常把一个数据库内部的事务处理,如对多个表的操作,作为本地事务看待。数据库的事务处理对象是本地事务,而分布式事务处理的对象是全局事务。
所谓全局事务,是指分布式事务处理环境中,多个数据库可能需要共同完成一个工作,这个工作即是一个全局事务,例如,一个事务中可能更新几个不同的数据库。对数据库的操作发生在系统的各处,但必须全部被提交或回滚。此时一个数据库对自己内部所做操作的提交不仅依赖本身操作是否成功,还要依赖与全局事务相关的其它数据库的操作是否成功,如果任一数据库的任一操作失败,则参与此事务的所有数据库所做的所有操作都必须回滚。
一般情况下,某一数据库无法知道其它数据库在做什么,因此,在一个 DTP 环境中,交易中间件是必需的,由它通知和协调相关数据库的提交或回滚。而一个数据库只将其自己所做的操作(可恢复)影射到全局事务中。
XA 就是 X/Open DTP 定义的交易中间件与数据库之间的接口规范(即接口函数)。
交易中间件用它来通知数据库事务的开始、结束以及提交、回滚等。
XA 接口函数由数据库厂商提供。
XA 与两阶段提交协议
通常情况下,交易中间件与数据库通过 XA 接口规范,使用两阶段提交来完成一个全局事务, XA 规范的基础是两阶段提交协议。
我们先了解一下以下三个概念:
- 网络通讯的危险期
- 一阶段提交(1PC)
- 两阶段提交(2PC)
网络通讯的危险期
一阶段提交(1PC One Phase Commit)
一阶段提交就是事务处理器向数据库服务器发出提交请求,然后等待数据库服务器的响应,收到响应后完成事务的提交,或者服务器返回提交失败的应答就回撤事务。危险期从发出请求开始,到收到应答结束,这段时间中数据库完成数据的修改、日志记录等处理,处理越复杂,危险期就越长。
两阶段提交(2PC Two Phase Commit)
两阶段提交把事务提交分成两个阶段:
第一阶段:事务处理器(或称事务协调器)向数据库服务器发出"准备提交"请求,数据库收到请求后执行相同的数据修改和日志记录等处理,不同的是处理完成后只是把事务的状态改成"可以提交",然后把结果返回给事务处理器。
第二阶段:事务处理器根据各数据库的响应再次发起请求。
- 如果在第一阶段内的危险期中发生了故障,事务处理器收不到回应,则认为事务失败,回撤事务。
- 数据库服务器收不到第二阶段的"确认提交"请求,把"可以提交"的事务回撤。
- 事务处理器向数据库服务器发出"确认提交"请求,数据库服务器把事务的"可以提交"状态改为"提交完成"状态,然后返回应答。
两阶段提交协议是实现分布式事务的关键。在此协议中,一个或多个资源管理器的活动均由一个称为事务协调器的单独软件组件来控制。
此协议中的五个步骤如下:
- 应用程序调用事务处理器中的提交方法。
- 事务处理器将联络事务中涉及的每个资源管理器,并通知它们准备提交事务(这是第一阶段的开始)。
- 为 了以肯定的方式响应准备阶段,资源管理器必须将自己置于以下状态:确保能在被要求提交事务时提交事务,或在被要求回滚事务时回滚事务。大多数资源管理器会 将包含其计划更改的日记文件(或等效文件)写入持久存储区中。如果资源管理器无法准备事务,它会以一个否定响应来回应事务处理器。
- 事务处理器收集来自资源管理器的所有响应。
- 在第二阶段,事务处理器将事务的结果通知给每个资源管理器。如果任一资源管理器做出否定响应,则事务处理器会将一个回滚命令发送给事务中涉及的所有资源管理 器。如果资源管理器都做出肯定响应,则事务协调器会指示所有的资源管理器提交事务。一旦通知资源管理器提交,此后的事务就不能失败了。通过以肯定的方式响应第一阶段,每个资源管理器均已确保,如果以后通知它提交事务,则事务不会失败。
通过两个顺序图来说明两阶段提交协议。
图 1 事务提交
图 1 显示事务成功(提交)。
图 2 事务被回滚
图 2 显示由于某种原因,其中一个资源管理器无法提交时的两阶段提交协议。
从严格意义上说,两阶段提交并没有完全解决网络通讯危险期的问题,但因为第二阶段的处理很简单,只是修改了事务的状态,与第一阶段相比其处理时间极短,所以危险期极短,发生事务提交故障的可能性几乎不存在。
实际应用
很多人会问:如果事务处理器只管理一个数据库资源,是不是可以只用一阶段提交的接口,如果要管理两个或以上的数据库资源就要使用两阶段提交的接口?
答案是否定的,用不用两阶段提交不是取决于数据库资源的个数,而是取决于通讯危险期的长短,即事务处理器与数据库服务器间的网络通讯质量。
如果事务处理器通过接口连接远程数据库,网络通讯质量不高,为了保证事务的完整性,即使只连接一个数据库也应该使用两阶段提交接口。
如果事务处理通过接口连接局域网上的数据库服务器,连接一个或多个数据库都可以使用一阶段提交接口。
管理多个数据资源的事务处理器中发生的事务可以修改所有相连的数据库,事务提交被分解为多个子事务,分别向各个数据库发出提交请求,这种事务也被称为全局事务。管理单个数据资源的事务处理器中发生的事务只能修改一个数据库,因而不会被分解,这种事务被称为本地事务。
虽然多数关于两阶段提交的资料都以全局事务的运作来说明两阶段提交的原理,但两阶段提交与全局事务并没有直接的联系。同一个事务处理器连接的多个数据资源要使用类型相同的接口,不能一些使用一阶段提交接口,另一些却使用两阶段提交接口,如果这样配置,全局事务的提交会失败。
两阶段提交的处理过程比一阶段提交复杂,所以效率也较低,大多数企业事务处理系统的事务处理器与数据库服务器运行在同一个计算中心内,以高速而稳定的网络相连接,甚至运行在同一台机器上,这种配置最好使用一阶段提交接口。
这时会引出第二个问题:一台服务器上的应用要连接一个本地的数据库(指运行在同一台机器上或连接在同一个高速的局域网上的数据库),同时也要通过不稳定的网络连接另一个远程数据库,该如何保证应用执行的事务完整性?
如果访问远程数据库的响应时间不会过长以至严重地影响整个事务的处理时间,仍然可以采用两阶段提交接口。否则应该采用另一种方案,在远程数据库一端安装一个服务器与该数据库通过一阶段提交接口相连,本地服务器上的应用要访问远程数据库时通过中间件平台间的互连机制向远程服务器发出处理请求,由远程服务器上的程序完成处理,整个事务的完整性由的分布式事务管理机制保证,这就已经超出了接口的功能范围了,具体的配置请参阅相关文档。