关于分布式事务、两阶段提交、一阶段提交、Best Efforts 1PC模式和事务补偿机制的研究

标签: 分布 阶段 阶段 | 发表时间:2015-11-05 18:02 | 作者:javafan_303
出处:http://www.iteye.com

 

 

1.XA

 

XA是由X/Open组织提出的分布式事务的规范。XA规范主要定义了(全局)事务管理器(Transaction Manager)和(局部)资源管理器(Resource Manager)之间的接口。XA接口是双向的系统接口,在事务管理器(Transaction Manager)以及一个或多个资源管理器(Resource Manager)之间形成通信桥梁。XA之所以需要引入事务管理器是因为,在分布式系统中,从理论上讲(参考Fischer等的论文),两台机器理论上无法达到一致的状态,需要引入一个单点进行协调。事务管理器控制着全局事务,管理事务生命周期,并协调资源。资源管理器负责控制和管理实际资源(如数据库或JMS队列)。下图说明了事务管理器、资源管理器,与应用程序之间的关系:

 

图1.XA规范下的分布式事务各类参与者之间的关系

 

2.JTA


作为java平台上事务规范JTA(Java Transaction API)也定义了对XA事务的支持,实际上,JTA是基于XA架构上建模的,在JTA 中,事务管理器抽象为javax.transaction.TransactionManager接口,并通过底层事务服务(即JTS)实现。像很多其他的java规范一样,JTA仅仅定义了接口,具体的实现则是由供应商(如J2EE厂商)负责提供,目前JTA的实现主要由以下几种:


1.J2EE容器所提供的JTA实现(JBoss)
2.独立的JTA实现:如JOTM,Atomikos.这些实现可以应用在那些不使用J2EE应用服务器的环境里用以提供分布事事务保证。如Tomcat,Jetty以及普通的java应用。

 

3.两阶段提交


所有关于分布式事务的介绍中都必然会讲到两阶段提交,因为它是实现XA分布式事务的关键(确切地说:两阶段提交主要保证了分布式事务的原子性:即所有结点要么全做要么全不做)。所谓的两个阶段是指:第一阶段:准备阶段和第二阶段:提交阶段。

 

图2.两阶段提交示意图(摘自info发布的《java事务设计策略》一文)



1.准备阶段:事务协调者(事务管理器)给每个参与者(资源管理器)发送Prepare消息,每个参与者要么直接返回失败(如权限验证失败),要么在本地执行事务,写本地的redo和undo日志,但不提交,到达一种“万事俱备,只欠东风”的状态。(关于每一个参与者在准备阶段具体做了什么目前我还没有参考到确切的资料,但是有一点非常确定:参与者在准备阶段完成了几乎所有正式提交的动作,有的材料上说是进行了“试探性的提交”,只保留了最后一步耗时非常短暂的正式提交操作给第二阶段执行。)

2.提交阶段:如果协调者收到了参与者的失败消息或者超时,直接给每个参与者发送回滚(Rollback)消息;否则,发送提交(Commit)消息;参与者根据协调者的指令执行提交或者回滚操作,释放所有事务处理过程中使用的锁资源。(注意:必须在最后阶段释放锁资源)

将提交分成两阶段进行的目的很明确,就是尽可能晚地提交事务,让事务在提交前尽可能地完成所有能完成的工作,这样,最后的提交阶段将是一个耗时极短的微小操作,这种操作在一个分布式系统中失败的概率是非常小的,也就是所谓的“网络通讯危险期”非常的短暂,这是两阶段提交确保分布式事务原子性的关键所在。(唯一理论上两阶段提交出现问题的情况是当协调者发出提交指令后当机并出现磁盘故障等永久性错误,导致事务不可追踪和恢复)

从两阶段提交的工作方式来看,很显然,在提交事务的过程中需要在多个节点之间进行协调,而各节点对锁资源的释放必须等到事务最终提交时,这样,比起一阶段提交,两阶段提交在执行同样的事务时会消耗更多时间。事务执行时间的延长意味着锁资源发生冲突的概率增加,当事务的并发量达到一定数量的时候,就会出现大量事务积压甚至出现死锁,系统性能就会严重下滑。这就是使用XA事务

4.一阶段提交(Best Efforts 1PC模式)

不像两阶段提交那样复杂,一阶段提交非常直白,就是从应用程序向数据库发出提交请求到数据库完成提交或回滚之后将结果返回给应用程序的过程。一阶段提交不需要“协调者”角色,各结点之间不存在协调操作,因此其事务执行时间比两阶段提交要短,但是提交的“危险期”是每一个事务的实际提交时间,相比于两阶段提交,一阶段提交出现在“不一致”的概率就变大了。但是我们必须注意到:只有当基础设施出现问题的时候(如网络中断,当机等),一阶段提交才可能会出现“不一致”的情况,相比它的性能优势,很多团队都会选择这一方案。关于在spring环境下如何实现一阶段提交,有一篇非常优秀的文章值得参考: http://www.javaworld.com/javaworld/jw-01-2009/jw-01-spring-transactions.html?page=5

5.事务补偿机制


像best efforts 1PC这种模式,前提是应用程序能获取所有的数据源,然后使用同一个事务管理器(这里指是的spring的事务管理器)管理事务。这种模式最典型的应用场景非数据库sharding莫属。但是对于那些基于web service/rpc/jms等构建的高度自治(autonomy)的分布式系统接口,best efforts 1PC模式是无能为力的,此类场景下,还有最后一种方法可以帮助我们实现“最终一致性”,那就是事务补偿机制。关于事务补偿机制是一个大话题,本文只简单提及,以后会作专门的研究和介绍。

 

6.在基于两阶段提交的标准分布式事务和Best Efforts 1PC两者之间如何选择

一般而言,需要交互的子系统数量较少,并且整个系统在未来不会或很少引入新的子系统且负载长期保持稳定,即无伸缩要求的话,考虑到开发复杂度和工作量,可以选择使用分布式事务。对于时间需求不是很紧,对性能要求很高的系统,应考虑使用Best Efforts 1PC或事务补偿机制。对于那些需要进行sharding改造的系统,基本上不应再考虑分布式事务,因为sharding打开了数据库水平伸缩的窗口,使用分布式事务看起来好像是为新打开的窗口又加上了一把枷锁。

补充:关于网络通讯的危险期

由于网络通讯故障随时可能发生,任何发出请求后等待回应的程序都会有失去联系的危险。这种危险发生在发出请求之后,服务器返回应答之前,如果在这个期间网 络通讯发生故障,发出请求一方无法收到回应,于是无法判断服务器是否已经成功地处理请求,因为收不到回应可能是请求没有成功地发送到服务器,也可能是服务 器处理完成后的回应无法传回请求方。这段时间称为网络通讯的危险期(In-doubt Time)。很显然,网络通讯的危险期是分布式系统除单点可靠性之外需要考虑的另一个可靠性问题。

参考资料:
本文原文连接:  http://blog.csdn.net/bluishglc/article/details/7612811 ,转载请注明出处!
1.百度百科
2.http://en.wikipedia.org/wiki/Java_Transaction_API
3.http://www.nosqlnotes.net/archives/62#more-62
4.http://hi.baidu.com/javaopensource/blog/item/0a2b764ec501b10cb3de05ba.html



已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [分布 阶段 阶段] 推荐:

分布式事务处理两阶段提交实例2

- - 行业应用 - ITeye博客
  Spring 通过AOP技术可以让我们在脱离EJB的情况下享受声明式事务的丰盛大餐.   通过配合使用ObjectWeb的JOTM开源项目,在不需要Java EE应用服务器的情况下,Spring也可以提供JTA事务. Sping对JTA支持的三种方式:. 直接集成JOTM提供JTA事务管理(无应用服务器支持,常用于单元测试).

Fix Bug的五个阶段

- Sirius - 酷壳 - CoolShell.cn
下面的文章和《各种流行的编程方式》有异曲同工,请你不要理解错了. 一个非常严重和困难的bug,能够成就一个饱经沧桑深受压力的有经验的专业程序员的职业生涯. 经受这种考验的创伤程度,相当你受到了一次严重的身体伤害,离婚,或是家庭成为的离世. 研究人员在研究了计算机编程心理学后,得出了一个程序员们在解决一个困难的bug时的心路里程.

逆境心理五阶段

- 冬虫夏草 - 科学松鼠会
原作:http://buttersafe.com/2010/05/20/the-five-stages/.

Nginx请求执行阶段

- - 操作系统 - ITeye博客
    Nginx在处理请求时,按照不同的阶段依次处理,常见的阶段如rewrite、access和content依次执行. Nginx中的指令一般只注册在某一个阶段,如echo注册在content阶段,set注册在rewrite阶段,因此set总是在echo之前执行,与书写顺序无关. 特殊的,geo和map指令与处理阶段无关,它们是声明性的.

TCC两阶段补偿型

- - 互联网 - ITeye博客
TCC方案是可能是目前最火的一种柔性事务方案了. 关于TCC(Try-Confirm-Cancel)的概念,最早是由Pat Helland于2007年发表的一篇名为《Life beyond Distributed Transactions:an Apostate’s Opinion》的论文提出. 在该论文中,TCC还是以Tentative-Confirmation-Cancellation命名.

关于分布式事务、两阶段提交、一阶段提交、Best Efforts 1PC模式和事务补偿机制的研究

- - 企业架构 - ITeye博客
XA是由X/Open组织提出的分布式事务的规范. XA规范主要定义了(全局)事务管理器(Transaction Manager)和(局部)资源管理器(Resource Manager)之间的接口. XA接口是双向的系统接口,在事务管理器(Transaction Manager)以及一个或多个资源管理器(Resource Manager)之间形成通信桥梁.

账号系统的两阶段登录和三阶段登录

- - idea's blog
简单的账号登录是一阶段登录, 也即用户提供用户名和密码, 然后服务器端验证账号和密码是否正确以决定是否成功登录. 一阶段登录其实安全性是非常危险了, 其危险性就在于这个登录流程涉及到的数据都是静态的, 因为用户名和密码一般不会改变.. 为了在登录流程中引入动态数据, 必须把流程改为两阶段登录: 1, 获取动态临时 secret salt; 2.

分布式系统中的一致性协议之两阶段提交协议(2PC)

- - 断尘居
 两阶段提交协议是很常见的解决分布式事务的方式,他可以保证分布式事务中,要么所有参与的进程都提交事务成功,要么都取消事务,这样做可以在分布式环境中保持ACID中A(原子性).      在两阶段提交协议中,包含了两种角色:协调者与参与者. 参与者就是实际处理事务的机器,而协调者就是其中一台单独的处理分布式事务的机器.

浏览器事件模型中捕获阶段、目标阶段、冒泡阶段实例详解

- - SegmentFault 最新的文章
如果对事件大概了解,可能知道有事件冒泡这回事,但是冒泡、捕获、传播这些机制可能还没有深入的研究实践一下,我抽时间整理了一下相关的知识. 本文主要对事件机制一些细节进行讨论,过于基础的事件绑定知识方法没有介绍. 特别少的篇幅关注浏览器兼容问题,毕竟原理了解了,兼容性问题可以自己想办法解决了. 在浏览器相对标准化之前,各个浏览器厂商都是自己实现的事件模型,有的用了冒泡,有的用了捕获,W3C为了兼顾之前的标准,将事件发生定义成如下三个阶段:.

漫画:成人的几个阶段

- Summer - 煎蛋
Radult/激进阶段:我能做想要做的. Sadult/悲观阶段:我希望我能做自己想做的. Madult/疯狂阶段:孩子们认为他想做什么就做什么,这简直是扯淡. Deadult/死:这不是我想要的. 漫画:如果将你的宠物放进盒子里会怎样. © 煎蛋 / 随便看看 / 图片托管于又拍网.