Ejb 简明教程

EJB - Transactions

事务是一个工作项的单一单元,它遵循 ACID 属性。ACID 代表原子性、一致性、隔离性和持久性。

  1. Atomic - 如果任何工作项失败,则整个单元将被视为失败。成功意味着所有项目都执行成功。

  2. Consistent - 事务必须使系统保持一致的状态。

  3. Isolated - 每个事务独立于任何其他事务执行。

  4. Durable - 如果事务已执行或提交,它应当能经受系统故障。

EJB 容器/服务器是事务服务器,并处理事务上下文传播和分布式事务。事务可以由容器管理,也可以由 Bean 代码中的自定义代码处理。

  1. Container Managed Transactions - 在此类型中,容器会管理事务状态。

  2. Bean Managed Transactions - 在此类型中,开发人员会管理事务状态的生命周期。

Container Managed Transactions

EJB 3.0 已指定了 EJB 容器实施的以下事务属性 −

  1. REQUIRED − 表示必须在事务中执行业务方法,否则将为该方法启动新事务。

  2. REQUIRES_NEW − 表示要为业务方法启动新事务。

  3. SUPPORTS − 表示业务方法将作为事务的一部分执行。

  4. NOT_SUPPORTED − 表示不应将业务方法作为事务的一部分执行。

  5. MANDATORY − 表示业务方法将作为事务的一部分执行,否则将抛出异常。

  6. NEVER − 表示如果业务方法作为事务的一部分执行,那么将抛出异常。

Example

package com.tutorialspoint.txn.required;

import javax.ejb.*

@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
public class UserDetailBean implements UserDetailRemote {

   private UserDetail;

   @TransactionAttribute(TransactionAttributeType.REQUIRED)
   public void createUserDetail() {
      //create user details object
   }
}

createUserDetail() 业务方法使用 Required 注解标记为 Required。

package com.tutorialspoint.txn.required;

import javax.ejb.*

@Stateless
public class UserSessionBean implements UserRemote {

   private User;

   @EJB
   private UserDetailRemote userDetail;

   public void createUser() {
      //create user
      //...
      //create user details
      userDetail.createUserDetail();
   }
}

createUser() 业务方法正在使用 createUserDetail()。如果在 createUser() 调用期间发生异常且未创建 User 对象,那么也不会创建 UserDetail 对象。

Bean Managed Transactions

在 Bean 管理的事务中,可以通过处理应用程序级别的异常来管理事务。

以下是需要考虑的关键点 −

  1. Start − 何时在业务方法中启动事务。

  2. Sucess − 在提交事务时识别成功场景。

  3. Failed − 在回滚事务时识别失败场景。

Example

package com.tutorialspoint.txn.bmt;

import javax.annotation.Resource;
import javax.ejb.Stateless;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.transaction.UserTransaction;

@Stateless
@TransactionManagement(value=TransactionManagementType.BEAN)
public class AccountBean implements AccountBeanLocal {

   @Resource
   private UserTransaction userTransaction;

   public void transferFund(Account fromAccount, double fund ,
      Account toAccount) throws Exception{

      try{
         userTransaction.begin();

         confirmAccountDetail(fromAccount);
         withdrawAmount(fromAccount,fund);

         confirmAccountDetail(toAccount);
         depositAmount(toAccount,fund);

         userTransaction.commit();
      }catch (InvalidAccountException exception) {
         userTransaction.rollback();
      }catch (InsufficientFundException exception) {
         userTransaction.rollback();
      }catch (PaymentException exception) {
         userTransaction.rollback();
      }
   }

   private void confirmAccountDetail(Account account)
      throws InvalidAccountException {
   }

   private void withdrawAmount() throws InsufficientFundException {
   }

   private void depositAmount() throws PaymentException{
   }
}

在此示例中,我们利用 UserTransaction 接口使用 userTransaction.begin() 方法调用标记事务的开始。我们使用 userTransaction.commit() 方法标记事务的完成,如果在事务期间发生任何异常,则使用 userTransaction.rollback() 方法调用回滚整个事务。