📜  EJB-事务(1)

📅  最后修改于: 2023-12-03 15:30:36.176000             🧑  作者: Mango

EJB-事务

EJB(Enterprise JavaBeans)是Java EE中的一种分布式组件技术,可以轻松构建企业级应用程序,同时也提供了强大的事务管理机制。

事务是指一系列操作的集合,这些操作必须都成功或都失败。在企业级应用程序中,需要保证一系列数据库操作的原子性、一致性、隔离性和持久性,这就需要使用到事务管理机制。

事务特性
  • 原子性:事务是一个不可再分割的整体,要么全部执行成功,要么全部回滚;
  • 一致性:事务执行前后,数据库数据的完整性没有被破坏;
  • 隔离性:多个事务之间互相独立,彼此不受影响;
  • 持久性:事务一旦提交,数据的修改将会被永久保存。
EJB事务管理机制

在EJB中,我们可以通过以下方式来使用事务:

  • 声明式事务:
    • 容器管理事务:容器负责管理事务,使用注解或xml文件配置;
    • Bean管理事务:Bean自己管理事务,通过调用UserTransaction接口的begin、commit、rollback方法手动管理。
  • 编程式事务:通过调用UserTransaction接口的方法来编写代码实现事务管理。
声明式事务

容器管理事务

通过注解配置

在EJB 3.0规范之后,通过在Bean类或方法上添加注解来声明事务。

@Stateless
public class UserServiceImpl implements UserService {

    @Inject
    private EntityManager entityManager;

    @Override
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void addUser(User user) {
        entityManager.persist(user);
    }

    //其他方法省略...
}

在注解中设置TransactionAttributeType属性,我们可以指定该方法使用的事务类型,包括REQUIRED、REQUIRES_NEW、SUPPORTS、NOT_SUPPORTED和MANDATORY。

通过xml文件配置

在EJB 2.1之前的版本,我们需要通过ejb-jar.xml文件来配置事务。

<entity>
    <ejb-name>UserServiceImpl</ejb-name>
    <transaction-type>Container</transaction-type>
    <persistence-type>Bean</persistence-type>
    <prim-key-class>java.lang.Long</prim-key-class>
    <reentrant>false</reentrant>
    <local-home>com.example.UserServiceLocalHome</local-home>
    <local>com.example.UserServiceLocal</local>
    <ejb-class>com.example.UserServiceImpl</ejb-class>
    <transaction-attributes>
        <method>
            <ejb-name>UserServiceImpl</ejb-name>
            <method-name>addUser</method-name>
            <trans-attribute>Required</trans-attribute>
        </method>
    </transaction-attributes>
</entity>

与注解配置相比,xml文件配置相对繁琐。

Bean管理事务

对于 Bean 管理的事务来说,我们需要手动去管理事务,这时可以通过注入 UserTransaction 来完成。我们需要手动去调用 begin() 方法以及 commit() 方法或 rollback() 方法。

下面是一个简单的示例:

@Stateless
public class UserServiceImpl implements UserService {

    @Resource
    private UserTransaction userTransaction;
    
    @Inject
    private EntityManager entityManager;

    @Override
    public void addUser(User user) {
        try {
            userTransaction.begin();
            entityManager.persist(user);
            userTransaction.commit();
        } catch (Exception e) {
            userTransaction.rollback();
            e.printStackTrace();
        } 
    }

    //其他方法省略...
}
编程式事务

除了使用注解或xml文件配置外,我们还可以使用编程式事务实现事务管理。

@Stateless
public class UserServiceImpl implements UserService {

    @Inject
    private EntityManager entityManager;

    @Override
    public void addUser(User user) {
        UserTransaction userTransaction = (UserTransaction) new InitialContext().lookup("java:comp/UserTransaction");
        try {
            userTransaction.begin();
            entityManager.persist(user);
            userTransaction.commit();
        } catch (Exception e) {
            userTransaction.rollback();
            e.printStackTrace();
        } 
    }

    //其他方法省略...
}
总结

EJB的事务是Java EE中强大的分布式事务机制,它提供了容器管理和Bean管理两种机制。通过使用声明式事务和编程式事务,程序员可以灵活地控制事务的操作,达到程序的正确性和鲁棒性。