在Java-EE中透明地管理每个请求的事务

时间:2014-01-27 16:28:19

标签: java java-ee transactions ejb

我正在开发一个JEE应用程序,其中对“facade”bean执行的每个请求都应该运行一个事务。

基本上,在每种方法中,我都可以这样做:

@Override
public void updateSalaries(float factor)
{
    initializeTransaction();
    // Actual business code...
    commitTransaction();
}

其中ùpdateSalaries()is a method invoked by the client, and where initializeTransaction()and commitTransaction()`分别负责获取/启动/提交/回滚(如果需要)事务。

不幸的是,事务管理应该更加透明:开发人员在编写业务方法时不应该关心的事情。

因此,某些“装饰”这些商业方法的方法会很好,但我想不出可行的方法。

我想到的另一个可能的解决方案是在中心DataAccessBean类中处理它,我将在@PostConstruct上启动事务并在@PreDestroy上提交:

@Stateless
public class DataAccessBean implements IDataAccessBean
{
    @PostConstruct
    public void initializeTransaction() { /* ... */ }

    @PreDestroy
    public void endTransaction() { /* ... */ }

    @Override
    public <T implements Serializable> T getObjectById(
        Class<T> objectType, Object key) { /* ... */ }

    @Override
    public void saveObject(Serializable object) { /* ... */ }
}
但是,我不确定,如果我能依靠这种机制。一个重要的问题也是,我需要什么类型的bean:我怀疑有状态bean是合适的,因为事务是按请求而不是每个会话。也许无状态bean是一个不错的选择,但AFAIK是一个无状态bean,当请求完成时(如果它驻留在无状态bean池中)可能不会被销毁。

两个小约束:

  • 解决方案不应依赖于特定的非标准框架或JEE服务器
  • 解决方案应与JEE 6和JEE 7兼容

感谢您的建议。

1 个答案:

答案 0 :(得分:1)

Java Transaction API(JTA)解决了您的需求。从JEE6教程(第八部分 - 第42章):

  

Java Transaction API(JTA)允许应用程序以某种方式访问​​事务   独立于特定的实现。 JTA规范了标准Java接口之间的接口   transactionmanager和参与分布式事务系统的各方:   事务性应用程序,Java EE服务器以及控制对共享的访问的管理器   受交易影响的资源。

您想要使用Container-Managed Transaction。在这个策略中,您只需要使用适当的事务属性装饰bean /方法,即:

@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) 
public void myMethod() {
...
}

如果您拥有服务服务(嵌套服务调用),服务层的设计必须仔细解决事务生命周期。