扯谈下XA事务

普通事务

普通事务的实现是比较好理解的。以jdbm3为例,大概是这样的过程:

每个事务都新建一个事务文件,当commit时,先把修改过的数据块,写到事务文件里,然后再一次性地写到数据库文件里。

如果commit时挂掉了,那么重启之后,会再次从事务文件里把修改过的块写到数据库文件里。最后再删除事务文件。

https://github.com/jankotek/JDBM3

但是XA事务,即所谓的分布式事务却令人感到云里雾里。一是资料很少,网上的各种配置资料都是流于表面;二是可能实际应用的人也少。

最近研究了下,算是找到点门道了。

二阶段提交(Two-phase Commit)

首先,XA事务是基于二阶段提交(Two-phase Commit)实现的。二阶段提交本身并没有什么令人疑惑的地方。看wiki就可以知道是怎么回事了。

简而言之,有二种角色,事务管理者(DM, Transaction Manager),资源管理器(RM, Resource Manager),通常即数据库或者JMS服务器。

下面两个图片来自:http://www.infoq.com/cn/articles/xa-transactions-handle

出错回滚:

当然,还有各种中间出错时,要处理的情况,详细可以看infoq的原文。

令人疑惑的atomikos

二阶段提交协议是很容易理解的,但是真正令我疑惑的是Java实现的atomikos,一个分布式事务的Transaction Manager组件。

开始的时候,我以为事务管理器(TM)都是独立的一个服务,或者一个独立的进程,它和资源管理器(RM)之间通过网络通迅。

但是在网上看一些atomikos配置文章,都没有提到如何配置一个独立的Transaction Manager,只是简单地介绍了下如何配置atomikos,这些配置都是和应用在一起的。

而从配置里面也没法看出是如何保证在事务过程中,如果应用的进程挂掉后,是如何恢复的。

再把atomikos的例子代码下载下来,发现也没有提到是如何保证事务在失败后,如何协调的。

比如,在第二段提交时,当RM1 commit完成了,而RM2 commit还没有完成,而这时TM,即配置了atomikos的应用程序崩溃,那么这个事务并没有完成,还需要TM重启后协调,才能最终完成这个事务。但是没看到恢复部分的配置。

没办法,只能亲自跑一遍代码了。

跑了下atomikos的代码,在第二阶段提交时,把进程杀掉,发现的确是可以自动处理回滚事务,或者再次提交的。那么信息是保存在哪里的?也没有看到有什么配置文件。

最终,只能下XA的规范下载下来,再一点点慢慢看。

在The XA Specification里的2.3小节:Transaction Completion and Recovery 明确提到TM是要记录日志的:

In Phase 2, the TM issues all RMs an actual request to commit or roll back the

transaction branch, as the case may be. (Before issuing requests to commit, the TM

stably records the fact that it decided to commit, as well as a list of all involved RMs.)

All RMs commit or roll back changes to shared resources and then return status to the

TM. The TM can then discard its knowledge of the global transaction.

TM是一定要把事务的信息,比如XID,哪个RM已经完成了等保存起来的。只有当全部的RM提交或者回滚完后,才能丢弃这些事务的信息。

于是再查看下atomikos例子运行目录,果然有一些文件日志文件:

127.0.1.1.tm13.epoch

tmlog13.log

tmlog.lck

tm.out

tm.out.lck

原来atomikos是通过在应用的目录下生成日志文件来保证,如果失败,在重启后可以通过日志来完成未完成的事务。

XA事务的假设条件

从XA的规范里找到了下面的说法:

The X/Open DTP model makes these assumptions:

TMs and RMs have access to stable storage    TM和RM都有牢靠的存储

TMs coordinate and control recovery   TM协调和控制恢复流程

RMs provide for their own restart and recovery of their own state. On request, an RM must give a TM a list of XIDs that the RM has prepared for commitment or has heuristically completed.   RM在得启和恢复时,得回应TM的请求,返回一系列的XID,是prepared的,或者是已经启发式地完成了的

也就是说,XA事务都假定了TM和RM都是有牢靠的存储的,所以也保证了TM重启后可以从日志里恢复还没处理完的事务。

TM可以向RM查询事务的状态,RM必须要返回一系列事务的XID,表明事务是prepared状态,还是已经commit的状态。

到这里,应该很明了了,XA事务是其限制的,而TM是XA事务的一个单点,TM必须要非常地牢靠。

从XA的接口函数,就可以大概看出协议是怎么工作的(来自XA规范文档):

如何避免XA事务

XA事务的明显问题是timeout问题,比如当一个RM出问题了,那么整个事务只能处于等待状态。这样可以会连锁反应,导致整个系统都很慢,最终不可用。

避免使用XA事务的方法通常是最终一致性。

举个例子,比如用户充值300元,为了减少DB的压力,先把这个放到消息队列里,然后后端再从消息队列里取出消息,更新DB。

那么如何保证,这条消息不会被重复消费?或者重复消费后,仍能保证结果是正确的?

  1. 在消息里带上用户帐号在数据库里的版本,在更新时比较数据的版本,如果相同则加上300;
  2. 比如用户本来有500元,那么消息是更新用户的钱数为800,而不是加上300;
  3. 另外建一个消息是否被消费的表,记录消息ID,在事务里,先判断消息是否已经消息过,如果没有,则更新数据库,加上300,否则说明已经消费过了,丢弃。

前面两种方法都必须从流程上保证是单方向的,不能插入其它的东东。

其它的一些东东:

貌似一直有人想用zookeeper来实现2pc,或者类似的东东,因为zookeeper是比较可靠的。但是感觉也没有办法解决timeout问题。

微软的XA事务恢复流程的文档:

http://msdn.microsoft.com/en-us/library/windows/desktop/ms681775(v=vs.85).aspx

There are two forms of XA transaction recovery, as follows:

  • Cold recovery. Cold recovery performed if the transaction manager process fails while a connection to an XA resource manager is open. When the transaction manager restarts, it reads the transaction manager log file and re-establishes the connection to the
    XA resource manager by calling xa_open_entry. It then initiates XA recover by calling xa_recover_entry.
  • Hot recovery. Hot recovery is performed if the transaction manager remains up while the connection between the transaction manager and the XA resource manager fails because the XA resource manager or the network fails. After the failure, the transaction
    manager periodically calls xa_open_entry to reconnect to the XA resource manager. When the connection is reestablished, the transaction manager initiates XA recovery by calling xa_recover_entry.

总结:

XA事务没有什么神秘的地方,二阶段提交也是一个人们很自然的一个处理方式。

只不过,这个是规范,如果有多个资源之间要协调,而且都支持XA事务,那么会比较方便 。

参考:

The XA Specification  可以从这里下载到:http://download.csdn.net/detail/hengyunabc/6940529

http://en.wikipedia.org/wiki/Two-phase_commit_protocol

http://www.infoq.com/cn/articles/xa-transactions-handle

http://java.sun.com/javaee/technologies/jta/index.jsp    

https://github.com/bitronix/btm  一个开源的JTA Transaction Manager

时间: 2024-09-20 23:10:46

扯谈下XA事务的相关文章

扯谈web安全之JSON

前言 JSON(JavaScript Object Notation),可以说是事实的浏览器,服务器交换数据的标准了.目测其它的格式如XML,或者其它自定义的格式会越来越少. 为什么JSON这么流行? 和JavaScript无缝对接是一个原因. 还有一个重要原因是可以比较轻松的实现跨域.如果是XML,或者其它专有格式,则很难实现跨域,要通过flash之类来实现. 任何一种数据格式,如何解析处理不当,都会存在安全漏洞.下面扯谈下JSON相关的一些安全东东. 在介绍之前,先来提几个问题: 为什么XM

MySQL · 特性分析 · 浅谈 MySQL 5.7 XA 事务改进

关于MySQL XA 事务 MySQL XA 事务通常用于分布式事务处理当中.比如在分库分表的场景下,当遇到一个用户事务跨了多个分区,需要使用XA事务 来完成整个事务的正确的提交和回滚,即保证全局事务的一致性. XA 事务在分库分表场景的使用 下图是个典型的分库分表场景,前端是一个Proxy后面带若干个MySQL实例,每个实例是一个分区. 假设一个表test定义如下,Proxy根据主键"a"算Hash决定一条记录应该分布在哪个节点上: create table test(a int p

MySQL数据库中对XA事务的限制

XA事务支持限于InnoDB存储引擎. MySQL XA实施是针对外部XA的,其中,MySQL服务器作为资源管理器,而客户端程序作为事务管理器.未实施"内部XA".这样,就允许MySQL服务器内的单独存储引擎作为RM(资源管理器),而服务器本身作为TM(事务管理器).处理包含1个以上存储引擎的XA事务时,需要内部XA.内部XA的实施是不完整的,这是因为,它要求存储引擎在表处理程序层面上支持两阶段提交,目前仅对InnoDB实现了该特性. 对于XA START,不支持JOIN和RESUME

mysql的XA事务恢复过程

mysql数据库开机报错: InnoDB: The log sequence number in ibdata files does not match InnoDB: the log sequence number in the ib_logfiles! 100224 12:24:20 InnoDB: Database was not shut down normally! InnoDB: Starting crash recovery. InnoDB: Reading tablespace

mysql的XA事务恢复过程详解_Mysql

mysql数据库开机报错: InnoDB: The log sequence number in ibdata files does not match InnoDB: the log sequence number in the ib_logfiles! 100224 12:24:20 InnoDB: Database was not shut down normally! InnoDB: Starting crash recovery. InnoDB: Reading tablespace

MySQL分布式事务(XA事务)

MySQL分布式事务(XA事务) 官网:https://dev.mysql.com/doc/refman/5.7/en/xa.html 1.什么是分布式事务 分布式事务就是指事务的参与者.支持事务的服务器.资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上.以上是百度百科的解释,简单的说,就是一次大的操作由不同的小操作组成,这些小的操作分布在不同的服务器上,且属于不同的应用,分布式事务需要保证这些小操作要么全部成功,要么全部失败.本质上来说,分布式事务就是为了保证不同数据库的数据一致

Mysql 第十日 字符集,XA事务,查询缓存

字符集和校对 客户端和服务器设置要要保持一致. 校对规则主要是mysql用来比较字符串,比如按照大小写敏感,或者是二进制. 分别对应了cs,ci(不敏感),bin三个对应项 可以指定校对规则对字段排序,但是这样可能会不使用原来的索引. 分布式事务 XA事务需要一个事务协调器来保证所有的事务参与者都完成了准备工作(第一阶段). 都准备好,则提交所有事务(第二阶段). Mysql不能扮演这个协调者,只能是参与节点. 内部XA 平衡多个存储引擎, 以及存储引擎和写二进制日志之间. 如果打开了写二进制日

斯诺登: FBI需要苹果才能解锁iPhone是扯谈

对于FBI说苹果才能解锁iPhone,斯诺登表示不服. 威锋网讯,说到美国在监控隐私方面的问题,爱德华·斯诺登或许会有一定的发言权.随着苹果和 FBI 事件的升级,依然流亡在外的斯诺登也发表了自己的看法. 近日,在一个名为"Blueprint for Democracy" 的峰会上,斯诺登就 FBI 要求苹果帮助解锁圣贝纳迪诺一案中的 iPhone 一事发表了看法.斯诺登表示:"FBI 说苹果拥有独家技术手段解锁 iPhone,那完全是扯谈(bullsh*t)."

谈下百度推广价格高的关键词的处理办法

摘要: 做百度推广的站长们一定会发现现在做竞价推广的网站越来越多,竞争非常激烈,价格更是一个劲的往上涨,如果没有一定的资金做后盾,一般的小企业小公司根本就禁不住如此烧钱的 做百度推广的站长们一定会发现现在做竞价推广的网站越来越多,竞争非常激烈,价格更是一个劲的往上涨,如果没有一定的资金做后盾,一般的小企业小公司根本就禁不住如此烧钱的推广方式,不过没办法,这也是见效最快的一种推广方式.因此,依然有很多的网站在做百度推广,那么,在做百度推广时价格高的词站长们是如何处理的呢?不能死拼价格,如果一个词的