首页 > Java开发 > JAVA平台事务管理

JAVA平台事务管理

事务是用户定义的操作序列,是一个逻辑工作单元。事务存在的目的是保证系统的正确性,保证系统对应的数据资源,如数据库、文件系统,以受控的方式操作,所以事务本身具有4个限定属性:原子性、一致性、隔离性、持久性。

一、     局部事务与全局事务

一个事务处理场景中,一般包含以下几个角色:

资源管理者:ResourceManger ,负责存储并管理系统数据资源的状态,如数据库服务器,JMS消息服务器等。

事务处理监视者:TransactionProcess Monitor,负责分布式事务场景中协调多个RM的事务处理。一般中间件或应用服务器担当此角色。

事务管理者:TransactionManager,可以认为是TP monitor的核心模块,直接负责RM事务处理,包括事务界定,事务上下文传递等功能。

应用程序:触发事务的边界点

事实上,并不是每个事务处理过程都包含这些角色,根据整个事务过程中涉及到资源管理者多少,可以分为局部事务与全局事务。这两类事务,具体的参与者不一样。

1.     全局事务

如果整个事务处理过程中,包含多个RM,那么就需要引入TP Monitor来协调多个RM之间的事务处理。

 

应用程序提交事务请求,TPMonitor调配之后,由TM统一协调,TM将使用两阶段协议来协调多个RM之间的事务处理。

2.     局部事务

如果当前事务中有一个资源管理者参与,那么当前事务就是局部事务。比如说一个系统只有一个数据源,或者有多个数据源,但每次事务只涉及到一个数据源。

 

局部事务中只涉及到一个RM,那TP Monitor就没有存在的必要,应用程序直接和RM打交道,通常情况下,RM都有内置的事务支持,如数据库的事务管理。局部事务,实践当中,更倾向使用内置事务支持,减少复杂度与事务开销。

二、     JAVA事务管理

在程序开发中,我们关心的是通过相应的产品API获取事务资源,考虑在业务逻辑中界定事务边界,并不关心各供应商如何实现事务。JAVA平台提供了各种各样的事务管理API,应用于局部事务场景与全局事务场景。

1.     局部事务支持

局部事务管理方式,不使用专门的事务管理API,而使用数据访问技术的API进行事务管理,局部事务随着数据访问技术的不同而异。从前面可知,局部事务RM都有内置事务支持,所以局部事务管理是基于数据访问技术所提供,应用程序与数据资源之间通信通道的API来管理事务,也就是说基于连接的API管理事务。

l  JDBC

JDBC是java平台数据访问最基础的API,基于java.sql.Connection,控制事务的提交与回滚。

Connection connection = ...

         connnection.setAutoCommit(false)

                   ...

         connection.commit();或connection.rollback();

l  Ibatis\Mybatis

mybatis是基于jdbc的封装,封装了jdbc模板代码,实现了实体与sql语句之间的映射。

SqlSession session = sqlSessionFractory.open(false);

                            ...

         session.commit();或session.rollback();

l  Hibernate

如果说mybatis是实体与sql之间的映射,那么hibernate是实体与表之间的映射。hibernate基于Session进行数据访问的事务管理(可以配置hibernate基于jdbc的局部事务管理,或者使用分布式事务管理)。

Session session = factory.open();

         Transaction transaction =session.beginTransaction;

                            ...

         transaction.commit(); 或 transaction.rollback();

l  JPA

JPA是一个持久化规范,hiberante是其中的一种实现方式(也是事实上的标准),其它实现还有TopLink、OpenJPA。JPA基于EntityManage进行事务管理。

EntityManger em = ...

em.getTransaction().begin();

                            ...

         em.getTransaction().commit() 或 em.getTransaction().rollback();

l  JMS

JMS是基于javax.jmx.Session进行事务控制。

Session session = ...

                            ...

                   session.commit(); 或 session.rollback();

 

局部事务管理常常涉及到一的一个问题是“连接”的传递,当在一个服务中包含多次数据访问时,数据访问层必须使用同一个“连接”,这是程序设计需要考虑的问题,否则无法地做到事务的原子性。

一般有两种思路解决这个问题,一个是参数传递,服务层开启连接(事务),传递给各个数据访问层;另一个是使用ThreadLocal,把“连接”绑定到线程上。

2.     全局事务支持

Java平台上的分布式事务,主要通过JTA支持。JTA是java标准分布式事务接口规范,具体实现由相应的供应商实现,各j2ee应用服务器需要提供对JTA的支持。除了应用服务器支持外,还有其它独立的JTA实现产品,如JOTM、Atomikos、JBoss Transaction等。

JTA采用X/Open XA实现两阶段协议,X/OpenXA接口是双向的系统接口,在事务管理器及资源管理者之间形成通售通道。仅在同一个事务上下文中需要协调多种资源时,才有必要使用X/Open XA接口。大多数场景,应用使用局部事务,单阶段提交,非必要引入XA数据库驱动,会导致不可预料的后果。

JTA是开发人员进行事务管理的接口,JTS是应用服务器使用的,实现了JTA的底层事务服务。

JTA进行分布式事务管理有两种方式:编程事务管理、声明性事务管理。

l  编程事务管理

使用编程事务管理,首先得获取Usertransaction,各应用服务器提供了JNDI查找服务。

InitialContext ctx = new InitialContext();

         UserTransaction transaction =ctx.lookup("UserTransaction");

                            ...

         transaction.commit() 或 transaction.rollback();

         其中不同的应用服务器给定的查找名称不同,如Jboss 查找名为“UserTransaction”,而Weblogic,查找名为"javax.transaction.UserTransaction"。

在EJB中时,编程事务管理又称之为BMT,Bean ManageTransaction。在EJB中需要使用配置文件或注解配置为BMT,Usertransaction可以直接从EJBContext中获取。

l  声明性事务管理

编程事务管理中,必须手动开启与结束事务,声明性事务管理,容器管理事务,开发人员不用编写任务代码,可以通过配置文件或注解,告诉容器如何管理事务。EJB声明性事务也称为容器管理事务,CMT,Container Manage Transaction。使用CMT,必须有EJB容器提供支持。

使用CMT仅要做的工作是配置事务属性,需要回滚时调用EJBContex方法setRollbackOnly()。

容器不会在应用发生异常时自行将事务标记为回滚,所有我们要在应用发生异常时告知容器回滚事务:setRollbackOnly()。

在CMT事务管理中,一个必然的决定,什么地方抛异常,什么地方和什么时机调用setRollbackOnly。一般的决策,开启事务的方法,具有事务管理的责任。

EJB中包含一个@ApplicationException注解,该注解告知应用服务器,当用异常抛出时是否自动将事务标记为回滚。带来的好处是不用写setRollbackOnly方法。缺点是注解针对异常类,只要抛出该异常,无论对象本身有没有开启事务,都会导致整体事务回滚,负责处理事务的方法无任何对回滚事务的补救。另一缺点是,将事务处理与异常处理混在一起,导致异常粒度过大。

三、     问题

JAVA平台提供的事务管理API多种多样,可以根据不的场景选择不同的事务管理API。但过多的选择,也带来一些问题。

1.        局部事务管理依赖于具体数据访问技术。事务管理代码与数据访问代码、业务代码混杂,将导致数据访问代码、业务代码不可重用;事务代码分散,降低了可重用性。

2.        无统一事务相关异常体系,需要事务管理代码处理checked exception.

3.        选择太多,缺少统一的事务抽象。

4.        CMT必须借助于EJB容器。CMT代码清晰,事务管理与业务代码分离,但受限于容器。

有需求就有解决方案,Spring事务框架,对事务管理与数据访问关注点进行了分离与抽象,使开发人员仅关心事务界定。

1.        http://baike.baidu.com/view/351106.htm

2.        http://www.ibm.com/developerworks/cn/java/j-lo-jta/

3.        spring framework refrerence

4.        spring 揭秘

5.        Java Transaction DesignStrategies


本文固定链接: http://www.devba.com/index.php/archives/866.html | 开发吧

报歉!评论已关闭.