您的位置:首页 > 其它

分布式事务

2015-11-17 10:34 211 查看
分布式事务和原子性

分布式事务(distributed transaction) 指的是包含多个事务资源的事务。事务资源指的是比如和关系型数据库和消息中间件通讯的连接器。通常这样的资源提供一些API比如begin(), rollback(), commit(). 在Java编程中, 事务资源通常显露为一个由底层平台提供的工厂产品:对于数据库而言,它是一个由DataSource产生的连接,或者Java Persistence API (JPA) EntityManager;对于Java Message Service (JMS)而言,它是一个会话(Session).

典型的一个用例, JMS消息触发一个数据库更新。一个成功的交互序列如下所示:

开始一个消息事务

获取消息

开始数据库事务

更新数据库

提交数据库事务

提交消息事务

如果一个数据库错误比如在更新时遇到约束冲突,理想的交互序列看起来如下

1. 开始消息事务

2. 接收消息

3. 开始数据库事务

4. 更新数据库, 失败!

5. 回滚数据库事务

6. 回滚消息事务

在 JAVA 中要想使用分布式事务处理,需要使用 JTA。但是 JTA 在 J2SE 环境中是没办法测试的,必须在 J2EE 应用服务器中。

建议,在 J2EE 容器上绑定 XA 的 DataSource,并且绑定 JTA 事务。在其他各应用中均使用 JNDI 从 J2EE 容器中获取连接,并开启事务。

J2EE 应用服务器为什么说会有好的、差的,免费的和商业的,其中最为重要的一点就是对于事务的处理能力。像开源的 J2EE 应用服务器在这一点上是没办法跟 WebLogic, WebSphere 这些商业 J2EE 应用服务器相比拟的。

在 J2EE 环境中使用 JTA 事务与 Local 事务的代码是一模一样的,对于开发人员来说这绝对是希望听到的。Local 事务就是通常所称的 Connection 的事务。

分布式事务一般采用一种称为 2-PC(两阶段提交)的协议进行处理,2-PC 是分布式事务处理协议。

比如说一个事务涉及 Oracle、MySQL 和 MS SQLServer 三个数据库的操作,举个最简单的例子,要在这三个数据库中各插入一条数据,但必须保持在一个事务中,要三个插入全部成功才算成功,如果只成功了一个或者两个,那么所有的操作都进行回滚,而 2-PC 就是用来干这事的。

两阶段提交需要有个中间协调人。在 Java 中只有 JTA 才能支持两阶段提交,而这个中间协调人就是 J2EE 应用服务器。

继续刚才那个事务,两个阶段如下:

一、各数据库在执行完 INSERT 后,J2EE 应用服务器在收到提交指令,这时通知各数据库进行事务提交准备。

数据库在收到响应后,进行准备工作,基本上是一个预提交工作,如果能提交则响应 J2EE 应用服务器是 能成功提交的,如果无法提交则响应 J2EE 应用服务器是无法提交的。

二、J2EE 应用服务器在收集到所有的响应之后进行判断,如果在第一阶段收到的信息都是可提交的,那么就通知所有的数据库进行提交;如果在第一阶段收到的信息有一个是无法提交的,那么就通知所有的数据库进行回滚操作。

通过这些步骤,可以看出分布式事务处理是很耗时的,也是相当麻烦的。因为数据库在第一阶段给事务协调器响应后如果能提交,在第二阶段就必须要保证事务能被提交,这是数据库要做的事情。

这里的 J2EE 应用服务器是 2-PC 的协调者。2-PC 在 JAVA 中不仅可以用于分布式数据库事务,也能应用于 JMS 事务。

要支持分布式事务,那么数据库就必须支持两阶段提交协议,否则是不能支持的。

例: 假设a对象为mysql数据源对象,b对象MS,c对象为oracle

try{

  a.beginTransaction();

//业务操作 insert

a.execute();

b.beginTransaction();

//业务操作 insert

b.execute();

c.beginTransaction();

//业务操作 insert

c.execute();

c.commit();

b.commit();

a.commit();

}catch(Exception e){

//全回滚

c.rollback();

b.rollback();

a.rollback();

}

finally{

c.close();

b.close();

a.close();

}

总结:

分布式事务,常见的两个处理办法就是两阶段式提交和补偿。

两段式提交典型的就是XA,有个事务协调器,告诉大家,来都准备好提交,大家回复,都准备好了,然后协调器告诉大家,一起提交,大家都提交了。

补偿比较好理解,先处理业务,然后定时或者回调里,检查状态是不是一致的,如果不一致采用某个策略,强制状态到某个结束状态(一般是失败状态),然后就Ok了。典型的就是冲正操作。

注:XA 接口规范 使用两阶段提交协议来完成一个全局事务,保证同一事务中所有数据库同时成功或者回滚。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: