XA 事务

X/A 事务

X/Open XA(扩展架构(eXtended Architecture)的缩写)是跨异构技术实现两阶段提交的标准,由 X/Open 国际联盟提出的 X/Open Distributed Transaction Processing(DTP)模型,简称 XA 协议。它于 1991 年推出并得到了广泛的实现:许多传统关系数据库(包括 PostgreSQL,MySQL,DB2,SQL Server 和 Oracle)和消息代理(包括 ActiveMQ,HornetQ,MSMQ 和 IBM MQ)都支持 XA。XA 不是一个网络协议,它只是一个用来与事务协调者连接的 C API。其他语言也有这种 API 的绑定;例如在 Java EE 应用的世界中,XA 事务是使用 Java 事务 API(JTA, Java Transaction API)实现的,而许多使用 Java 数据库连接(JDBC, Java Database Connectivity)的数据库驱动,以及许多使用 Java 消息服务(JMS)API 的消息代理都支持 Java 事务 API(JTA)。

XA 假定你的应用使用网络驱动或客户端库来与参与者进行通信(数据库或消息服务)。如果驱动支持 XA,则意味着它会调用 XA API 以查明操作是否为分布式事务的一部分;如果是,则将必要的信息发往数据库服务器。驱动还会向协调者暴露回调接口,协调者可以通过回调来要求参与者准备,提交或中止。事务协调者需要实现 XA API。标准没有指明应该如何实现,但实际上协调者通常只是一个库,被加载到发起事务的应用的同一个进程中(而不是单独的服务)。它在事务中个跟踪所有的参与者,并在要求它们准备之后收集参与者的响应(通过驱动回调),并使用本地磁盘上的日志记录每次事务的决定(提交/中止)。

如果应用进程崩溃,或者运行应用的机器报销了,协调者也随之往生极乐。然后任何带有准备了但未提交事务的参与者都会在疑虑中卡死。由于协调程序的日志位于应用服务器的本地磁盘上,因此必须重启该服务器,且协调程序库必须读取日志以恢复每个事务的提交/中止结果。只有这样,协调者才能使用数据库驱动的 XA 回调来要求参与者提交或中止。数据库服务器不能直接联系协调者,因为所有通信都必须通过客户端库。

X/Open 组织(即现在的 Open Group)定义了分布式事务处理模型。X/Open DTP 模型(1994)包括应用程序(AP)、事务管理器(TM)、资源管理器(RM)、通信资源管理器(CRM)四部分。一般,常见的事务管理器(TM)是交易中间 件,常见的资源管理器(RM)是数据库,常见的通信资源管理器(CRM)是消息中间件。通常把一个数据库内部的事务处理,如对多个表的操作,作为本地事务看待。数据库的事务处理对象是本地事务,而分布式事务处理的对象是全局事务。所谓全局事务,是指分布式事务处理环境中,多个数据库可能需要共同完成一个工作,这个工作即是一个全局事务,例如,一个事务中可能更新几个不同的数据库。对数据库的操作发生在系统的各处但必须全部被提交或回滚。此时一个数据库对自己内部所做操作的提交不仅依赖本身操作是否成功,还要依赖与全局事务相关的其 它数据库的操作是否成功,如果任一数据库的任一操作失败,则参与此事务的所有数据库所做的所有操作都必须回滚。一般情况下,某一数据库无法知道其它数据库在做什么,因此,在一个 DTP 环境中,交易中间件是必需的,由它通知和协调相关数据库的提交或回滚。而 一个数据库只将其自己所做的操作(可恢复)影射到全局事务中。

DTP 模型图

XA 就是 X/Open DTP 定义的交易中间件与数据库之间的接口规范(即接口函数),交易中间件用它来通知数据库事务的开始、结束以及提交、回滚等。XA 接口函数由数据库厂商提供。二阶提交协议和三阶提交协议就是根据这一思想衍生出来的。可以说二阶段提交其实就是实现 XA 分布式事务的关键,下面分别来看看 XA 事务成功和失败的模型图:

二阶段成功

二阶段失败

XA 规范的限制

XA 事务解决了保持多个参与者(数据系统)相互一致的现实的重要问题,但正如我们所看到的那样,它也引入了严重的运维问题。特别来讲,这里的核心认识是:事务协调者本身就是一种数据库(存储了事务的结果),因此需要像其他重要数据库一样小心地打交道:

  • 如果协调者没有复制,而是只在单台机器上运行,那么它是整个系统的失效单点(因为它的失效会导致其他应用服务器阻塞在存疑事务持有的锁上)。令人惊讶的是,许多协调者实现默认情况下并不是高可用的,或者只有基本的复制支持。

  • 许多服务器端应用都是使用无状态模式开发的(受 HTTP 的青睐),所有持久状态都存储在数据库中,因此具有应用服务器可随意按需添加删除的优点。但是,当协调者成为应用服务器的一部分时,它会改变部署的性质。突然间,协调者的日志成为持久系统状态的关键部分,与数据库本身一样重要,因为协调者日志是为了在崩溃后恢复存疑事务所必需的。这样的应用服务器不再是无状态的了。

  • 由于 XA 需要兼容各种数据系统,因此它必须是所有系统的最小公分母。例如,它不能检测不同系统间的死锁(因为这将需要一个标准协议来让系统交换每个事务正在等待的锁的信息),而且它无法与 SSI 协同工作,因为这需要一个跨系统定位冲突的协议。

  • 对于数据库内部的分布式事务(不是 XA),限制没有这么大,例如,分布式版本的 SSI 是可能的。然而仍然存在问题:2PC 成功提交一个事务需要所有参与者的响应。因此,如果系统的任何部分损坏,事务也会失败。因此,分布式事务又有**扩大失效(amplifying failures)**的趋势,这又与我们构建容错系统的目标背道而驰。

下一页