用EJB进行事务管理

            最近在实践java项目中,遇到了很多的注解,通过百度发现,这些注解内部其实蕴含着大学问,下面我来说一下@TransactionManagement

           在EJB中有两种使用事务的方式。第一种方式通过容器管理的事务,叫CMT(Container-Managed Transaction),另一种通过Bean管理的事务叫BMT(Bean-Managed Transaction)。
 
         如果使用容器来管理事务,那么EJB组件就不需要显式地给出begin 、commit 、abort 语句,EJB 容器会替我们考虑这些内容。EJB 容器会依据EJB组件提供者指定的事务行为来界定相应的事务边界。
         在使用容器管理事务时,EJB 容器会拦截客户请求,并自动为EJB组建启动新的事务,也就是说,容器会通过begin 语句调用底层事务系统,从而启动事务。随后,容器会将业务请求委派给EJB组件,组件中的业务操作将运行在这一事务中。处于事务中的EJB 组件能够执行任何业务逻辑,如写入数据库、发送异步信息、调用其他的EJB组件等。一旦在处理业务过程中出现问题,则EJB 组建需要通知EJB 容器去回滚事务。当EJB 组建完成业务处理后,会将控制权交回给EJB 容器。随后,EJB容器能够通过commit
或abort 语句调用底层事务系统。
       我们可以使用@TransactionAttribute注释或部署描述符来指定事务属性。EJB 容器通过分析事务属性便能够知道如何处理EJB 组件的事务需求。

        如果用简短的话总结上面的内容就是,用CMT管理事务,事务都是被容器管理的,开发人员不需要对事务进行管理,需要做的就是配置事务属性.
 
      EJB 事务属性的取值有以下几种:
 
(1 )Required ,如果EJB组件必须总是运行在事务中,则应该使用Required 模式。如果已经有事务在运行,则EJB 组件参与其中;如果没有事务运行,则EJB 容器会为EJB组件启动新的事务。
 
           Required 是默认和最常使用的事务属性值。这个值指定必须在事务之内调用EJB方法。如果从非事务性客户端调用方法,那么容器会在调用方法之前开始事务,并且在方法返回时结束事务。另一方面,如果调用者从事务性上下文调用方法,那么方法会联结已有事务。在从客户段传播事务的情况下,如果我们的方法表示应该回滚事务,那么容器不仅回回滚整个事务,而且会向客户端抛出异常,从而让客户端知道它开始的事务已经被另一个方法回滚了。
 
(2 )Requires_New,当客户调用EJB 时,如果总是希望启动新的事务,则应该使用RequiresNew 事务属性,如果客户在调用EJB组件时已经存在事务,则当前事务会被挂起,进而容器启动新的事务,并将调用请求委派给EJB组件。也就是说,如果客户端已经有了事务,那么它暂停该事务,知道方法返回位置,新事务是成功还是失败都不会影响客户端已有的事务。EJB组件执行相应的业务操作,容器会提交或回滚事务,最终容器将恢复原有的事务,当然,如果客户在调用EJB 组件时不存在事务,则不需要执行事务的挂起或恢复操作。
 
           RequiresNew 事务属性非常有用。如果EJB 组件需要事务的ACID属性,并且将EJB 组件运行在单个独立的工作单元中,从而不会将其他外部逻辑也包括在当前的事务中,则必须使用RequiredNew事务属性。如果需要事务,但是不希望事务的回滚影响客户端,就应该使用它。另外,当不希望客户端的回滚影响你的时候,也应该使用这个值。
 
(3 )Supports ,如果某个EJB组件使用了Supports 事务属性,则只有调用它的客户已经启用了事务时,这一EJB 组件才会运行在事务中。如果客户并没有运行在事务中,则EJB组建也不会运行在事务中。Supports 同Required 事务属性很相似,但是,Required 要求EJB 组件必须运行在事务中。如果使用Support事务属性,EJB 组建很可能没有运行在事务中。
 
(4 )Mandatory ,Mandatory事务属性要求调用EJB 组件的客户必须已经运行在事务中。如果从非事务性客户端调用使用Mandatory 属性的EJB方法,那么客户将接受到系统抛出的javax.ejb.EJBTransactionRequiredException 异常。EJB 组件使用Mandatory事务属性是非常安全的,它能够保证EJB 组建运行在事务中。如果客户没有运行在事务中,则不能够调用到应用了Mandatory 事务属性的EJB组件。但是,Mandatory 事务属性要求第3 方(及客户)在调用EJB
组件前必须启动了事务。EJB 容器并不会为Mandatory事务属性自动启动新事务,这是同Support 事务属性的最主要区别。
 
(5 )NotSupported ,如果EJB组件使用了NotSupport事务属性,它根本不会参与到事务中。如果调用者使用相关联的事务调用方法,容器就会暂停事务,调用方法,然后再方法返回时恢复事务。通常,此属性只用于非实物性的自动确认模式中,支持JMS提供者的MDB 。
 
(6 )Never ,如果EJB组件使用Never 事务属性,它就不能够参与到事务中,而且,如果调用它的客户已经处于事务中,则容器会将javax.ejb.EJBException异常抛给客户。

            当然在上面所列出的属性中我们最常用的还是Required具体可以看下面的一段片段代码:

<span style="font-size:18px;">import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
@Stateless(name = "UserManager")
@Remote
@TransactionManagement(TransactionManagementType.CONTAINER)
public class UserManagerBean implements UserManager {
   @PersistenceContext
    private EntityManager em ;
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
   public void addUser(String name) {
      User s = new User();
      s.setName(name);
      em.persist(s);
      System.out.println("服务器端执行成功:保存姓名" + name);
     }
}
</span>

 
        

          上面的例子中

             @TransactionManagement(TransactionManagementType.CONTAINER)表示指定事务的类型。如果省略,默认为CMT方式。

             @TransactionAttribute(TransactionAttributeType.REQUIRED)通知容器如何管理事务,事务的属性控制了事务的使用范围,因为事务之间的关系非常的复杂,这个属性主要是用来处理事务与事务之间怎样来处理的的问题。

   
 以上便是EJB用容器来进行事务管理,在这里我们还发现了一个注解:@Stateless

     下面我来讲讲这个注解的意思:

     

1)有状态会话bean:每个用户有自己特有的一个实例,在用户的生存期内,bean保持了用户的信息,即“有状态”;一旦用户灭亡(调用结束或实例结束),bean的生命期也告结束。即每个用户最初都会得到一个初始的bean。生命周期我们可以用web中context去简单认识,比如session、request等。在这个生命周期内,用户只会得到一个特定的stateful会话bean。

 

2)无状态会话bean:bean一旦实例化就被加进会话池中,各个用户都可以共用。即使用户已经消亡,bean的生命期也不一定结束,它可能依然存在于会话池中,供其他用户调用。由于没有特定的用户,那么也就不能保持某一用户的状态,所以叫无状态bean。但无状态会话bean并非没有状态,如果它有自己的属性(变量),那么这些变量就会受到所有调用它的用户的影响,这是在实际应用中必须注意的。

时间: 2015-08-30

用EJB进行事务管理的相关文章

Spring事务管理高级应用难点剖析,第1部分

概述 Spring 最成功,最吸引人的地方莫过于轻量级的声明式事务管理,仅此一点,它就宣告了 重量级 EJB 容器的覆灭.Spring 声明式事务管理将开发者从繁复的事务管理代码中解脱出来 ,专注于业务逻辑的开发上,这是一件可以被拿来顶礼膜拜的事情.但是,世界并未从此消停 ,开发人员需要面对的是层出不穷的应用场景,这些场景往往逾越了普通 Spring 技术书籍的 理想界定.因此,随着应用开发的深入,在使用经过 Spring 层层封装的声明式事务时,开发 人员越来越觉得自己坠入了迷雾,陷入了沼泽,

Spring的声明式事务管理

在service类前加上@Transactional,声明这个service所有方法需要事务管理.每一个业务方法开始时都会打开一个事务. Spring默认情况下会对运行期例外(RunTimeException)进行事务回滚.这个例外是unchecked 如果遇到checked意外就不回滚. 如何改变默认规则: 1 让checked例外也回滚:在整个方法前加上 @Transactional(rollbackFor=Exception.class) 2 让unchecked例外不回滚: @Trans

详解Java的Spring框架中的事务管理方式_java

数据库事务是被当作单个工作单元的操作序列.这些操作要么全部完成或全部不成功.事务管理是面向企业应用程序,以确保数据的完整性和一致性RDBMS中的重要组成部分.事务的概念可以用下面的描述为ACID四个关键属性来描述: 原子性: 一个事务应该被视为单个操作单元表示的操作的任一整个序列是成功的或不成功的. 一致性: 这代表了数据库的参照完整性,在桌等唯一主键的一致性 隔离性: 可能有很多事务处理相同的数据集的同时,每个事务都应由他人隔离,以防止数据损坏. 持久性: 一旦事务完成,本次事务的结果必须作出

浅析Spring提供的事务管理方法

Spring提供的事务管理可以分为两类:编程式的和声明式的.编程式的,比较灵活,但是代码量大,存在重复的代码比较多:而声明式的比编程式的更灵活方便.本文将讨论这两种事务管理的区别. 传统的JDBC事务管理 以往使用JDBC进行数据操作时,一般采用DataSource,从数据源中得到Connection,我们知道数据源是线程安全的,而连接不是线程安全的,所以对每个请求都是从数据源中重新取出一个连接.一般的数据源由容器进行管理,包括连接池.例如TOMCAT,WEBSPHERE,WEBLOGIC等这些

spring的事务管理配置

一般的,我们把事务配在service层,利用service的业务逻辑接口统一的管理. 为什么不用在dao层呢? 因为一个service有可能调用多个dao,而这多个dao有可能相互联系,有时候一个操作需要调用多次数据库,但是这多次调用要么全提交,要么全回滚. 因此,在dao层调用事务理论上说不是一个很明智的选择.应该有业务逻辑层service层负责事务,统一处理. Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource.TransactionManager和代理机制这三

spring提供的事务管理

spring提供的事务管理可以分为两类:编程式的和声明式的.编程式的,比较灵活,但是代码量大, 存在重复的代码比较多:声明式的比编程式的更灵活.编程式主要使用transactionTemplate.省略了部 分的提交,回滚,一系列的事务对象定义,需注入事务管理对象:声明式:主要使用 TransactionProxyFactoryBean,围绕Poxy的动态代理,能够自动的提交和回滚事务.统观spring事务, 围绕着两个核心PlatformTransactionManager和Transacti

Spring事务管理高级应用难点剖析: 第2部分

联合军种作战的混乱 Spring 抽象的 DAO 体系兼容多种数据访问技术,它们各有特 色,各有千秋.像 Hibernate 是非常优秀的 ORM 实现方案,但对底层 SQL 的控制不太方便: 而 iBatis 则通过模板化技术让您方便地控制 SQL,但没有 Hibernate 那样高的开发效率:自 由度最高的当然是直接使用 Spring JDBC 莫属了,但是它也是最底层的,灵活的代价是代码的 繁复.很难说哪种数据访问技术是最优秀的,只有在某种特定的场景下,才能给出答案.所以 在一个应用中,往

全面分析Spring的编程式事务管理及声明式事务管理

开始之前 关于本教程 本教程将深入讲解 Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务.通过对本教程的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之. 先决条件 本教程假定您已经掌握了 Java 基础知识,并对 Spring 有一定了解.您还需要具备基本的事务管理的知识,比如:事务的定义,隔离级别的概念,等等.本文将直接使用这些概念而不做详细解释.另外,您最好掌握数据库的基础知识,虽然这不是必须. 系统需求 要试验这份教程中的工具和示例,硬件配置需求为:至少带

Spring框架的事务管理应用分析

引言 在软件开发中出现过各种各样的框架,开源软件的兴起,使得各种各样的框架纷纷出现,例如,Apache组织下就拥有诸多的框架类产品.框架就是一组协同工作的类,它们为特定类型的软件构筑了一个可重用的设计.然而,传统的框架使得应用程序组件过分依赖于框架中的类,这种耦合度的提高降低了组件的复用性.Spring框架的出现,使得组件之间更松散的耦合成为了可能. Spring框架简介 Spring框架是一个2003年2月才出现的开源项目,该开源项目起源自Rod Johnson在2002年末出版的<Exper