`
ldsjdy
  • 浏览: 146876 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

EJB事务

    博客分类:
  • EJB
阅读更多
转载自:
http://fansofjava.iteye.com/blog/350119
事务分本地事务和分布式事务,本地事务相对简单,这里讨论一下分布事事务。
分布式环境如何管理涉及一个以上资源的事务呢?主要是通过被称为两阶段
提交(two-phase commit)来实现的。在执行一个以上的数据库操作时,如果第一个数据库操作成功,第二个数据库操作失败,要回滚第一个操作是非常困难的。所以在提交事务之前,两阶段提交协议会询问每个资源管理器的当前事务能否提交成功,如果任何一个资源管理器表示不能提交事务,那么就回滚整个事务。

EJB有两种使用事务的方式。
第一种方式通过容器管理的事务,叫CMT,另一种通过bean管理的事务叫BMT。

在CMT中,容器自动提供事务的开始、提交和回滚。总是在业务方法的开始和结束处标记事务的边界。下面以ejb3 in action上的例子说明:

Java代码  收藏代码

   1. @Stateless  
   2. @TransactionManagement(TransactionManagementType.CONTAINER)  
   3. public class OrderManagerBean {  
   4.     @Resource                                                  
   5.     private SessionContext context;                       
   6. …  
   7. @TransactionAttribute(TransactionAttributeType.REQUIRED)                             
   8.  
   9.     public void placeSnagItOrder(Item item, Customer customer){  
  10.         try {  
  11.             if (!bidsExisting(item)){  
  12.                 validateCredit(customer);  
  13.                 chargeCustomer(customer, item);  
  14.                 removeItemFromBidding(item);  
  15.             }  
  16.         } catch (CreditValidationException cve) {                    
  17.             context.setRollbackOnly();                               
  18.         } catch (CreditProcessingException cpe){                     
  19.             context.setRollbackOnly();                               
  20.         } catch (DatabaseException de) {                             
  21.             context.setRollbackOnly();                              
  22.         }                                                           
  23.     }  
  24. }  

@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
public class OrderManagerBean {
    @Resource                                                
    private SessionContext context;                     

@TransactionAttribute(TransactionAttributeType.REQUIRED)                           

    public void placeSnagItOrder(Item item, Customer customer){
        try {
            if (!bidsExisting(item)){
                validateCredit(customer);
                chargeCustomer(customer, item);
                removeItemFromBidding(item);
            }
        } catch (CreditValidationException cve) {                  
            context.setRollbackOnly();                             
        } catch (CreditProcessingException cpe){                   
            context.setRollbackOnly();                             
        } catch (DatabaseException de) {                           
            context.setRollbackOnly();                            
        }                                                         
    }
}



其中,@TransactionAttribute(TransactionAttributeType.REQUIRED)表示指定事务的类型。
如果省略,默认为CMT方式。
@TransactionAttribute(TransactionAttributeType.REQUIRED)通知容器如何管理事务,
事务的属性控制了事务的使用范围,因为事务之间的关系非常的复杂,这个属性主要是用来处理事务与事务之间怎样来处理的的问题。
具体作用见附件图片。

如果产生一个系统异常,容器将自动回滚该事务。 EJBException是RuntimeException的子类,即也是一个系统运行时异常。
如果Bean抛出一个普通的非继承自RutimeException应用异常,事务将不会自动回滚,但可以
通过调用EJBContext的SetRollbackOnly回滚。
当然EJB上下文还有一个getRollbackOnly方法,通过返回一个boolean值来确定CMT事务是否已被标记为回滚。如果开始非常耗资源的操作前判断此bean的事务已被标记为回滚,则可以节约很多系统资源。
对于上面的异常回滚操作,还有一更加优雅的方式:


Java代码  收藏代码

   1. public void placeSnagItOrder(Item item, Customer customer)  
   2.     throws CreditValidationException, CreditProcessingException,      
   3.         DatabaseException {                                           
   4.     if (!bidsExisting(item)){                                        
   5.         validateCredit(customer);                                     
   6.         chargeCustomer(customer, item);                              
   7.         removeItemFromBidding(item);  
   8.     }                                                                
   9. }  
  10. ...  
  11. @ApplicationException(rollback=true)                                 
  12. public class CreditValidationException extends Exception {           
  13. ...  
  14. @ApplicationException(rollback=true)                                 
  15. public class CreditProcessingException extends Exception {          
  16. ...  
  17. //系统异常 
  18. @ApplicationException(rollback=false)                                 
  19. public class DatabaseException extends RuntimeException {  

public void placeSnagItOrder(Item item, Customer customer)
    throws CreditValidationException, CreditProcessingException,    
        DatabaseException {                                         
    if (!bidsExisting(item)){                                      
        validateCredit(customer);                                   
        chargeCustomer(customer, item);                            
        removeItemFromBidding(item);
    }                                                              
}
...
@ApplicationException(rollback=true)                               
public class CreditValidationException extends Exception {         
...
@ApplicationException(rollback=true)                               
public class CreditProcessingException extends Exception {        
...
//系统异常
@ApplicationException(rollback=false)                               
public class DatabaseException extends RuntimeException {



@ApplicationException把JAVA核对与不核对的异常标识为应用程序异常。其rollback默认为false,表示程序不会导致CMT自动回滚。
但应用程序异常应当慎用,见下文:

If the container detects a system exception, such as an  ArrayIndexOutOfBounds or
NullPointerException that you did not guard for, it will still roll back the CMT transaction.
However, in such cases the container will also assume that the Bean is in inconsistent state and will
destroy the instance. Because unnecessarily destroying Bean instances is costly, you should never
delibertely use system exceptions.

2.bean管理事务

由于CMT依靠容器开始、提交和回滚事务,所以会限制事务的边界位置。而BMT则允许通过编程的方式来指定事务的开始、提交和回滚的位置。主要使用的是javax.transaction.UserTransaction接口。

如下面代码:

Java代码  收藏代码

   1. @Stateless)  
   2. @TransactionManagement(TransactionManagementType.BEAN)                                   
   3. public class OrderManagerBean {  
   4.     @Resource                                                        
   5.     private UserTransaction userTransaction;                         
   6.   
   7.     public void placeSnagItOrder(Item item, Customer customer){  
   8.         try {  
   9.             userTransaction.begin();                                 
  10.             if (!bidsExisting(item)){  
  11.                 validateCredit(customer);  
  12.                 chargeCustomer(customer, item);  
  13.                 removeItemFromBidding(item);  
  14.             }  
  15.             userTransaction.commit();                                 
  16.         } catch (CreditValidationException cve) {                    
  17.             userTransaction.rollback();                              
  18.         } catch (CreditProcessingException cpe){                    
  19.             userTransaction.rollback();                             
  20.         } catch (DatabaseException de) {                           
  21.             userTransaction.rollback();                         
  22.         } catch (Exception e) {  
  23.             e.printStackTrace();  
  24.         }  
  25.     }  
  26. }  

@Stateless)
@TransactionManagement(TransactionManagementType.BEAN)                                 
public class OrderManagerBean {
    @Resource                                                      
    private UserTransaction userTransaction;                       

    public void placeSnagItOrder(Item item, Customer customer){
        try {
            userTransaction.begin();                               
            if (!bidsExisting(item)){
                validateCredit(customer);
                chargeCustomer(customer, item);
                removeItemFromBidding(item);
            }
            userTransaction.commit();                               
        } catch (CreditValidationException cve) {                  
            userTransaction.rollback();                            
        } catch (CreditProcessingException cpe){                  
            userTransaction.rollback();                           
        } catch (DatabaseException de) {                         
            userTransaction.rollback();                       
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}




@TransactionManagement(TransactionManagementType.BEAN) 指定了事务的类型为BMT,上面没有用到@TransactionAttribute,因为它只适用于CMT,在上面代码中,可以显示的指定事务的开始与提交,因此更加的灵活。上面最关键的地方是注入了UserTransaction资源。其中获得UserTransaction资源的方式有三种,除了用 EJB资源的方式注入以外,还有以下两种方式:
(1) JNDI查找
Java代码  收藏代码

   1. Context context = new InitialContext();  
   2. UserTransaction userTransaction =   
   3.  (UserTransaction) context.lookup(“java:comp/UserTransaction”);  
   4. userTransaction.begin();  
   5. // Perform transacted tasks.  
   6. userTransaction.commit();  

Context context = new InitialContext();
UserTransaction userTransaction = 
(UserTransaction) context.lookup(“java:comp/UserTransaction”);
userTransaction.begin();
// Perform transacted tasks.
userTransaction.commit();



如果在EJB之外,则可使用此方法,如在不支持依赖注入的JBoss4.2.2的Web工程或helper class即帮助器类中都可以。

(2)EJBContext

Java代码  收藏代码

   1. @Resource   
   2. private SessionContext context;  
   3. ...  
   4. UserTransaction userTransaction = context.getUserTransaction(); userTransaction.begin();  
   5. // Perform transacted tasks.  
   6. userTransaction.commit();  

@Resource 
private SessionContext context;
...
UserTransaction userTransaction = context.getUserTransaction(); userTransaction.begin();
// Perform transacted tasks.
userTransaction.commit();



注意:getUserTransaction方法只能在BMT中使用。如果在CMT中使用,则会抛出IllegalStateException 异常。且在BMT中不能使用EJBContext的getRollbackOnly和setRollbackOnly方法,如果这样使用,也会抛出 IllegalStateException异常。



如果使用有状态的Session Bean且需要跨越方法调用维护事务,那么BMT是你唯一的选择,当然BMT这种技术复杂,容易出错,且不能连接已有的事务,当调用BMT方法时,总会暂停已有事务,极大的限制了组件的重用。故优先考虑CMT事务管理。
分享到:
评论

相关推荐

    EJB与事务 -详细描述EJB和事务

    EJB与事务-详细描述EJB和事务,是javaEE初学者的好材料

    EJB的事务属性

    EJB 具有事务的处理属性

    EJB3-JBOSS7-分布式事务示例

    该资源是下面帖子的资料,可以进去看看帖子再下载,这样能防止下的东西没用。。。。 http://blog.csdn.net/qzh3578/article/details/46489747

    ejb3.0 分布式事务

    关于ejb3.0 分布式事务的demo,涉及到相关persistence.xml 配置以及数据源配置。

    EJB葵花宝典(题集)

    目录 1技术总述 7 2开发环境介绍 7 2.1搭建开发环境 7 2.2MyEclipse 10 3SessionBean(会话Bean) 18 3.1会话Bean调用架构 18 3.2会话Bean的客户 18 3.3会话Bean的组成 19 ...6EJB事务 76 7定时器 77 8拦截器 77

    eventos-javaee6:应用程序演示EJB事务的操作

    JavaEE6活动我们将演示维护干净代码以及如何使用Events和TransactionAttributeType的良好实践。 [优良作法]使用SOLID原则之一的“单一责任原则”的概念。 这是“单一职责” ,“封闭式” ,“ Liskov替换” ,“接口...

    ejb之实体Bean与cloudscape数据库事务处理代码

    j2ee1.3中实体Bean与之附带的数据库之间实现事务处理!

    EJB 3.0从入门到精通

    全书共分16章,内容依次包含了Java EE概述、EJB基础、搭建EJB环境、会话bean、持久化实体、持久化实体管理器、对象关系映射、JPQL查询、消息驱动bean、事务、提高EJB 3.0性能、从Web层访问EJB 3和EJB安全、EJB和Web...

    深入浅出EJB

    你会深入地了解EJB体系结构、会话、实体和消息驱动bean的生命周期、CMP、EJBQL、事务、安全、模式等等内容,还会知道基于组件的开发究竟是什么意思。你理解得越多,需要记的就越少,所以不要指望一点都不懂,通过死...

    EJB设计模式(PDF)

    本书不仅是高级设计模式的最佳指志,而且解决...本书还包括以下内容:架构模式、事务和持久性模式、客户端交互模式、主键一成策略。用Ant构建系统的最佳实践、JUnit测试策略。如何使用JDO和EJB作为企业bean的替代工具。

    ejb3.0培训教程与源码(绝对精品)

    1) 事务:够用 2)安全:不够用 3)资源管理和组件的声明周期的管理; 4)远程的调用:屏蔽了很多细节 5)并发请求 ( EJB都是单线程的 ); 不要在EJB的代码中写多线程的代码; 6)集群 7)负载均衡 5, EJB的类型 1) ...

    Java数据编程指南

    Enterprise JavaBeans Enterprise JavaBean体系结构 一个简单的Enterprise JavaBean 会话Beaus 面向对象与关系模型 实体beans 数据映射 EJB事务置 EJB 2.0 小结 第20章 Java事务API...

    J2EE应用开发详解

    199 11.5.1 JMS 200 11.5.2 消息驱动Bean的生命周期 202 11.5.3 创建消息驱动Bean 202 11.6 实体Bean 203 11.6.1 实体Bean的特性 204 11.6.2 实体Bean的分类及组成 204 11.6.3 EJB 3.0中的实体Bean 206 11.7 EJB事务 ...

    Java数据库编程宝典2

    1.3 事务管理和事务控制命令 1.3.1 ACID测试 1.3.2 SQL中的事务管理 1.4 数据库安全和数据控制语言 1.4.1 管理数据库用户 1.4.2 用户权限 1.4.3 用户组和角色 1.5 数据库体系结构 1.5.1 Java数据对象 ...

    Java数据库编程宝典4

    1.3 事务管理和事务控制命令 1.3.1 ACID测试 1.3.2 SQL中的事务管理 1.4 数据库安全和数据控制语言 1.4.1 管理数据库用户 1.4.2 用户权限 1.4.3 用户组和角色 1.5 数据库体系结构 1.5.1 Java数据对象 ...

    Java数据库编程宝典1

    1.3 事务管理和事务控制命令 1.3.1 ACID测试 1.3.2 SQL中的事务管理 1.4 数据库安全和数据控制语言 1.4.1 管理数据库用户 1.4.2 用户权限 1.4.3 用户组和角色 1.5 数据库体系结构 1.5.1 Java数据对象 ...

    Java数据库编程宝典3

    1.3 事务管理和事务控制命令 1.3.1 ACID测试 1.3.2 SQL中的事务管理 1.4 数据库安全和数据控制语言 1.4.1 管理数据库用户 1.4.2 用户权限 1.4.3 用户组和角色 1.5 数据库体系结构 1.5.1 Java数据对象 ...

    EJB入门及高级特性

    轻松学会EJB,包括开发流程,事务处理,Entity基础和高级特性,Time Service,安全,Web Service,会话Bean,消息驱动bean,资源注入

    EJB3开发指南《EJB.3.Developer.Guide》

    EJB3开发指南英文版《EJB.3.Developer.Guide》 出版商:...第七章:事务 第八章:发送消息Messaging 第九章:EJB Timer Serivce 第十章:Intercepters 第十一章:实现EJB3的WebSerivce 第十二章:EJB3安全

Global site tag (gtag.js) - Google Analytics