文档章节

EJB3 事务控制

mn_1127
 mn_1127
发布于 2015/09/30 15:17
字数 1206
阅读 422
收藏 1

一、EJB的事务管理分如下两个方面:

    1、CMT(容器管理事务)

    2、BMT(Bean管理事务)

二、CMT介绍:

  容器管理事务主要是通过容器自动控制事务的开启,提交和回滚,开发人员不需要手工编写代码,由容器来控制事务的边界,一般来说是业务方法的开始

是事务的开启,业务方法的结束是事务的提交部分,当程序遇到运行时异常,事务会自动回滚。

      如果遇到的是非运行时异常想要回滚事务的话可以用SessionConText的setRollBackOnly()方法来达到目的。下面的例子是一个使用CMT的例子:(事务的控制我们一般放在Service层,而不是Dao层)。

    示例程序1:(参考publicEJB组件的NewhouseManagerImpl类)

@Stateless(name = "newhouseManager") //状态定义实列Bean 提供远程JNDI
@Remote(INewhouseManager.class)//定义远程接口
@Local(INewhouseManager.class)//定义本地接口
@TransactionManagement(TransactionManagementType.CONTAINER)  // 这里来定义是CMT还是BMT
public class NewhouseManagerImpl implements INewhouseManager{       

    @EJB(beanName = "newhouseDAO") //注入dao
    private IGenericDAO<Newhouse, Integer> newhouseDAO;
      
    @TransactionAttribute(TransactionAttributeType.REQUIRED)  //这里来定义事务的传播特性,如果调用该组件的客户方已经开启了事务则加入原事务,否则开启一个新事务
    public Newhouse save(Newhouse entity) {
        LogUtil.log("saving Newhouse instance", Level.INFO, null);
        try {
            LogUtil.log("save successful", Level.INFO, null);
            entity.setBname("测试1:" + new Date());
            newhouseDAO.create(entity); //插入第一条记录,此时事务还没有提交,数据库里面看不到该记录
            Newhouse entity2 = new Newhouse();
            entity2.setBname("测试2");
            entity2.setPath(null); // 这里设置path为null的话,会出现运行时异常,事务会回滚,entity1和entity2将不会插入到public库的newhouse表中
            newhouseDAO.create(entity2);
        } catch (RuntimeException re) {
            LogUtil.log("save failed", Level.SEVERE, re);
            re.printStackTrace();  
            return null;
        }
    }
 }

    PS:这里特别要注意:当newhouseDAO这个类的create方法抛出的是非运行时异常时,这里假设插入第一条记录时时成功的,插入第二天记录时抛出了非运行时异常,那么ejb的事物是不会回滚的,当遇到这种情况时,需要像以下操作(也就是用SessionContext的setRollbackOnly()方法进行事物回滚):

    示例程序2:

@Stateless(name = "newhouseManager") //状态定义实列Bean 提供远程JNDI
@Remote(INewhouseManager.class)//定义远程接口
@Local(INewhouseManager.class)//定义本地接口
@TransactionManagement(TransactionManagementType.CONTAINER)  // 这里来定义是CMT还是BMT
public class NewhouseManagerImpl implements INewhouseManager{       
    @Resource
    private SessionContext context;
    
    @EJB(beanName = "newhouseDAO") //注入dao
    private IGenericDAO<Newhouse, Integer> newhouseDAO;
      
    @TransactionAttribute(TransactionAttributeType.REQUIRED)  //这里来定义事务的传播特性,如果调用该组件的客户方已经开启了事务则加入原事务,否则开启一个新事务
    public Newhouse save(Newhouse entity) {
        LogUtil.log("saving Newhouse instance", Level.INFO, null);
        try {
            LogUtil.log("save successful", Level.INFO, null);
            entity.setBname("测试1:" + new Date());
            newhouseDAO.create(entity); //插入第一条记录,此时事务还没有提交,数据库里面看不到该记录
            Newhouse entity2 = new Newhouse();
            entity2.setBname("测试2");
            entity2.setPath(null); // 这里设置path为null的话,会出现运行时异常,事务会回滚,entity1和entity2将不会插入到public库的newhouse表中
            newhouseDAO.create(entity2);
        } catch (Exception re) {
            context.setRollbackOnly();
            LogUtil.log("save failed", Level.SEVERE, re);
            re.printStackTrace();  
            return null;
        }
    }
 }


三、BMT介绍

  BMT主要是通过手工编程来实现事务的开启、提交和回滚,相对于CMT来说虽然增加了工作量,但是控制力度更细,而且更加灵活,我们可以再出现异常的时候回滚事务,也可以通过JMS返回或者远程调用返回值来控制事务的回滚或提交;使用BMT需要用到UserTransaction这个类的实例来实现事务的begin、commit和rollback,可以通过Ejb注解的方式获得这个类实例,也可以用EJBContext.getUserTransaction来获得。下面是一个使用BMT的例子:

    示例程序3:

@Stateless(name = "newhouseManager") //状态定义实列Bean 提供远程JNDI
@Remote(INewhouseManager.class)//定义远程接口
@Local(INewhouseManager.class)//定义本地接口
@TransactionManagement(TransactionManagementType.BEAN) //设置为BMT事务
public class NewhouseManagerImpl implements INewhouseManager{        

    @Resource
    private UserTransaction ut; //注入UserTransaction
    
    @EJB(beanName = "newhouseDAO") //注入dao
    private IGenericDAO<Newhouse, Integer> newhouseDAO;
     
    @TransactionAttribute(TransactionAttributeType.REQUIRED)  //设置事务的传播特性为required
    public Newhouse save(Newhouse entity) {
        LogUtil.log("saving Newhouse instance", Level.INFO, null);
        try {
            ut.begin();
            LogUtil.log("save successful", Level.INFO, null);
            entity.setBname("测试1:" + new Date());
            newhouseDAO.create(entity);   
            Newhouse entity2 = new Newhouse();
            entity2.setBname("测试2");
            entity2.setPath(null);
            newhouseDAO.create(entity2);
            ut.commit();            
           } catch(RuntimeException e) {
          ut.rollBack();
           }
   }
  }

四、跨多个数据库的事务控制(JTA事务)

     如果想要在一个事务操作中控制多个数据库的操作,需要如下两步操作:

1、需要设置persistence.xml里面的datasouce支持jta事务,另外设置transaction-type为jta,如下所示:

<persistence-unit name="public_master"  transaction-type="JTA">
      <jta-data-source>java:/public_master_db</jta-data-source>
      <properties>
          <property name="hibernate.dialect" value="com.jiwu.core.utils.BlobMySQLDialect"/>
          <property name="hibernate.hbm2ddl.auto" value="update"/>
          <property name="hibernate.show_sql" value="false" />
      </properties>
</persistence-unit>

2、修改jboss安装目录下的\server\default\conf\jbossjta-properties.xml

在<properties depends="arjuna" name="jta">这个节点下,添加一个子节点<property name="com.arjuna.ats.jta.allowMultipleLastResources" value="true"/>

本文转载自:http://www.cnblogs.com/jiwuyf/p/3794777.html

mn_1127
粉丝 6
博文 23
码字总数 6952
作品 0
杭州
后端工程师
私信 提问
J2EE核心之EJB

EJB作为EJB是sun的JavaEE服务器端组件模型,设计目标与核心应用是部署分布式应用程序。简单来说就是把已经编写好的程序(即:类)打包放在服务器上执行。凭借java跨平台的优势,用EJB技术部署...

邵鸿鑫
2016/04/27
0
0
JBoss6.0+EJB3中Message-DrivenBean的"HelloWorld"实现

JBoss6.0 + EJB3 中Message-Driven Bean 的"HelloWorld" 实现。 目的:了解 EJB3 中Message-Driven Bean的开发过程及其工作原理。 开发步骤: 1)开发服务端。编写Message-Driven Bean类。 2)......

空云万里晴
2012/10/30
1K
0
深入浅出JBoss Seam

什么是Seam? JBoss Seam是“Java EE 5.0的一个轻量级的框架”。这是什么意思?难道Java EE(Enterprise Edition) 5.0本身不是一套“框架吗”?为什么在官方规范之外,还需要另外一个框架?好...

红薯
2008/09/07
2.7K
4
JBoss AS 5.0.0.GA 正式版本发布

JBoss AS 5.0 GA 正式版发布了,这是一个完全兼容 Java EE 5.0 规范,并经过 Java EE 认证的版本。 JBoss AS5中,大部分显著的新特性添加都源自于要将所有主要的JBoss子系统带到下一个阶段去...

红薯
2008/12/05
1K
0
SSH与SSH2这种框架组合的历史原由

早在2001年时当时的J2EE推崇的是EJB,EJB被称为J2EE的核心,当时要学J2EE就是Servlet+EJB,在EJB里其实早已经有了AOP与实体映射这些概念了。 EJB有三种形态的BEAN,SessionBean, Entity Bea...

天行健J
2012/11/20
477
0

没有更多内容

加载失败,请刷新页面

加载更多

自建redis笔记

自建redis笔记 最近在linux安装了一下redis,特做一些笔记! 本文先单节点启动redis,然后再进行持久化配置,在次基础上,再分享搭建主从模式的配置以及Sentinel 哨兵模式及集群的搭建 单节点...

北极之北
24分钟前
4
0
vue+element之多表单验证

方法一:利用promise var p1=new Promise(function(resolve, reject) { this.$refs[form1].validate((valid) => { if(valid){ ......

沉迷代码我爱学习
26分钟前
4
0
golang 1.13 errors 包 新函数介绍

引 这次 errors 包算重量级更新。很有更能把以前的一些设计模式给推到。下面聊下用法。 error 装包 以前返回一个错误,想要保存 error 链,还要定义结构体保存以前的 error 信息。感兴趣看下...

guonaihong
35分钟前
53
0
并发编程之线程池

一、线程池 1、什么是线程池 Java中的线程池是运用场景最多的并发框架,几乎所有需要异步或并发执行任务的程序 都可以使用线程池。在开发过程中,合理地使用线程池能够带来3个好处。 第一:降...

codeobj
38分钟前
5
0
知识点总结思维导图模板分享,良心安利,建议收藏

思维导图经常被用在学习中,对大脑思维进行发散,对知识进行记忆。使用思维导图可以让知识更加简单更有层次。下面是利用思维导图所绘制的几款知识点总结思维导图模板,大家可以进行进行参考使...

干货趣分享
41分钟前
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部