- EJB教程
 - EJB - 主页
 - EJB - 概述
 - EJB - 环境设置
 - EJB - 创建应用程序
 - EJB-无状态Bean
 - EJB - 有状态 Bean
 - EJB-持久性
 - EJB - 消息驱动 Bean
 - EJB - 注释
 - EJB-回调
 - EJB-定时器服务
 - EJB - 依赖注入
 - EJB-拦截器
 - EJB - 可嵌入对象
 - EJB - Blob/Clob
 - EJB - 事务
 - EJB-安全性
 - EJB - JNDI 绑定
 - EJB - 实体关系
 - EJB - 访问数据库
 - EJB - 查询语言
 - EJB - 异常处理
 - EJB-Web 服务
 - EJB - 打包应用程序
 
- EJB 有用资源
 - EJB - 快速指南
 - EJB - 有用的资源
 - EJB - 讨论
 
EJB - 事务
事务是单个工作项单元,遵循 ACID 属性。ACID 代表Atomics、一致、隔离和持久。
Atomics- 如果任何工作项失败,整个单元将被视为失败。成功意味着所有项目都成功执行。
一致- 事务必须使系统保持一致状态。
隔离- 每笔交易的执行独立于任何其他交易。
持久- 如果事务已被执行或提交,则它应该能够在系统故障中幸存下来。
EJB 容器/服务器是事务服务器,处理事务上下文传播和分布式事务。事务可以由容器或 bean 代码中的自定义代码处理来管理。
容器管理事务- 在这种类型中,容器管理事务状态。
Bean 管理事务- 在这种类型中,开发人员管理事务状态的生命周期。
容器管理的事务
EJB 3.0 指定了 EJB 容器实现的以下事务属性 -
REQUIRED - 表示业务方法必须在事务中执行,否则将为该方法启动一个新事务。
REQUIRES_NEW - 表示要为业务方法启动一个新事务。
SUPPORTS - 表示业务方法将作为事务的一部分执行。
NOT_SUPPORTED - 指示业务方法不应作为事务的一部分执行。
MANDATORY - 指示业务方法将作为事务的一部分执行,否则将引发异常。
NEVER - 指示如果业务方法作为事务的一部分执行,则将引发异常。
例子
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
   }
}
使用Required注释将createUserDetail()业务方法设置为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 管理的事务
在 Bean Managed Transactions 中,可以通过在应用程序级别处理异常来管理事务。
以下是需要考虑的要点 -
开始- 何时在业务方法中开始事务。
成功- 确定提交事务时的成功场景。
失败- 确定事务回滚时的失败场景。
例子
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()方法调用回滚整个事务。