我正在开发一个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池中)可能不会被销毁。
两个小约束:
感谢您的建议。
答案 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() {
...
}
如果您拥有服务服务(嵌套服务调用),服务层的设计必须仔细解决事务生命周期。