`
ldsjdy
  • 浏览: 151130 次
  • 性别: 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和事务

    Bean管理的事务需要开发者自己编写代码来控制事务的开始和提交,而容器管理的事务则由EJB容器自动处理,开发者只需要在ejb-jar.xml中声明事务属性,容器会根据这些属性自动进行事务管理,简化了编程工作。...

    EJB的事务属性

    在深入探讨EJB(Enterprise JavaBeans)的事务属性之前,我们先来理解一下EJB的基本概念及其在企业级应用中的重要性。EJB是Java EE平台的核心组件之一,主要用于构建可扩展、健壮且安全的企业级应用程序。它提供了一...

    EJB3-JBOSS7-分布式事务示例

    **EJB3-JBOSS7-分布式事务示例** EJB3(Enterprise JavaBeans 3.0)是Java EE平台中的一个核心组件,它提供了一种标准的方式来创建可部署在服务器上的分布式、面向服务的企业级应用程序。EJB3引入了许多改进,包括...

    ejb3.0 分布式事务

    【ejb3.0 分布式事务详解】 在企业级Java应用中,EJB(Enterprise JavaBeans)3.0提供了一种强大而灵活的方式来处理分布式事务。分布式事务是指跨越多个数据库或资源管理器的单一逻辑操作,确保了数据的一致性和...

    ejb spring

    2. **Spring AOP与ejb事务管理**:Spring的声明式事务管理可以与ejb的事务管理相结合,提供更细粒度的事务控制。 3. **Spring与ejb的协作**:在某些场景下,会话bean可能只负责协调工作,而具体的业务逻辑由Spring...

    EJB实体Bean与事物管理

    - EJB事务通常通过抛出受检查异常(Checked Exception)来控制事务的回滚。如果方法抛出了未检查异常(Unchecked Exception)或Error,容器默认会回滚事务。 6. **示例应用** - 在EJB实体Bean的实现中,一个常见...

    第一个EJB简单例子

    4. **EJB事务管理**: - 容器管理的事务(CMT):容器负责开始、提交或回滚事务。 - bean管理的事务(BMT):由Bean自己控制事务边界。 5. **EJB安全性**: - 角色和权限:定义不同用户群体(角色)以及他们对...

    电子书-EJB3.0实例教程

    3. **简化事务管理**:EJB 3.0简化了事务管理,开发者可以通过`@TransactionAttribute`注解定义事务的属性,如REQUIRED、REQUIRES_NEW等,无需像EJB 2.x那样处理复杂的EJB事务API。 4. **依赖注入**:EJB 3.0引入了...

    EJB003软件开发考试培训资料

    - EJB事务管理:EJB支持声明式事务,通过在方法上添加事务属性(如@TransactionAttribute)来定义事务边界。容器负责事务的开始、提交、回滚等操作,也可以使用编程式事务管理,由开发者显式控制。 总的来说,EJB...

    EJB实验 网上商城

    3. **EJB事务管理** - EJB容器自动管理事务,确保操作的原子性和一致性,这对于处理如订单支付等关键业务操作至关重要。 4. **安全性和访问控制** - EJB支持角色基的访问控制(RBAC),可以限制特定用户或角色对...

    精通EJB源代码 第二版

    5. **并发与事务**:讨论多线程环境下EJB的同步机制,以及EJB事务的ACID属性和隔离级别。 6. **Web服务集成**:介绍如何将EJB与SOAP或RESTful Web服务集成,以实现跨系统通信。 7. **源代码分析**:通过分析具体...

    EJB 用户指南

    #### 六、EJB事务管理 EJB提供了两种事务管理机制: 1. **容器管理事务 (Container Managed Transaction, CMT):** - 由容器自动管理事务边界。 - 开发者只需关注业务逻辑,无需显式地管理事务。 2. **Bean管理...

    各种EJB之间的调用示例.7z

    5. **EJB事务管理** - EJB容器自动管理事务,可以根据方法的声明(如`@TransactionAttribute(REQUIRED)`)决定事务边界。 - 对于错误处理,EJB支持异常回滚,保证数据一致性。 6. **安全性** - EJB支持角色基的...

    基于Java的实例源码-各种EJB之间的调用示例.zip

    4. EJB事务管理: - 容器管理的事务(Container-Managed Transactions, CMT):容器自动管理事务的开始、提交、回滚。 - 应用程序管理的事务(Application-Managed Transactions, AMT):由bean自己管理事务,需要...

    EJB3.0入门精与通集.rar

    - EJB事务管理 - EJB安全性,如角色基础访问控制(RBAC) - EJB的并发控制,如无状态会话bean的并发实例管理 - JPA的查询语言JPAQL和Criteria API - EJB与Web服务的集成 - EJB在微服务架构中的应用 通过学习和掌握...

    EJB Design Pattern

    7. **事务管理**:详细介绍了EJB事务的ACID属性和不同类型的事务边界。 8. **安全模式**:涵盖了身份验证、授权和审计机制,以确保系统的安全性。 9. **设计原则与最佳实践**:涵盖了面向接口编程、单一职责原则、...

Global site tag (gtag.js) - Google Analytics