我正在使用JSF 2.1,EJB 3.1,JPA 2.0,Glassfish 3.1.1和NetBeans 7.0.1。EJB JPA事务
对于每个实体类,我创建了一个单独的Facade类,例如,使用NetBeans工具的UserFacade和AddressFacade。这两个实体彼此不相关,并且彼此完全独立。但是,我需要在一次事务中将它们放入数据库中,并且如果插入失败,则应该还原另一个应该回滚的数据。我怎样才能做到这一点?据我所知,EJB容器本身管理事务,并且不允许手动控制事务边界。
我正在使用JSF 2.1,EJB 3.1,JPA 2.0,Glassfish 3.1.1和NetBeans 7.0.1。EJB JPA事务
对于每个实体类,我创建了一个单独的Facade类,例如,使用NetBeans工具的UserFacade和AddressFacade。这两个实体彼此不相关,并且彼此完全独立。但是,我需要在一次事务中将它们放入数据库中,并且如果插入失败,则应该还原另一个应该回滚的数据。我怎样才能做到这一点?据我所知,EJB容器本身管理事务,并且不允许手动控制事务边界。
的交易将只要你们俩在同你的实体“触摸”坚持,更新或删除,但是,你说他们是不相关的回滚一切对方无论如何,所以我猜你必须执行2持续存在,这不会在同一个交易范围。
选项1
你可以做一些简单而丑陋的人,这一点,有@PrePersist和@PreUpdate在JPA,你可以确保一切都与以前的坚持。这会造成糟糕的代码库并强制不需要的依赖关系。
选项2
你可以简单地拥有用户和地址之间的关系,这是很自然的。
选项3
第三个选择是使用Bean Managed Transaction
在非常基本的情况下,EJB的每个公共方法都在一个事务中执行,该事务在方法内抛出异常时回退。
因此,如果您在同一个方法中创建两个实体,创建将被包装在一个事务中。
在我的情况下,我有两个调用EJB公共方法。例如,userFacade.create(user)和addressFacade(address)在一个方法内部。但是,userFacade和addressFacade是两个不同Facade类的两个不同实例,并且这两个实体被放入两个不同的事务中,我检查了自己。当一个实体未能放入数据库时,第二个实体已成功插入数据库。 – Nurjan 2012-01-17 12:09:15
您应该重构您的代码,以便共同执行的操作以相同的业务方法执行。 – tobiasbayer 2012-01-17 12:20:16
您可以自行控制交易。该功能被称为Bean-Managed Transactions(BMT)。你可以阅读更多关于他们here。
你也需要了解TransactionManagement
的事情。 Oracle在这个article中描述了它。
例子:
@Stateless
@TransactionManagement(TransactionManagementType.BEAN)
public class MyEJB implements MyEJBLocal {
@Resource
private EJBContext context;
@PersistenceContext
private EntityManager em;
public void doMyAction() {
UserTransaction transaction = context.getUserTransaction();
transaction.begin();
... create myEntity ...
em.persist(myEntity);
transaction.commit();
}
}
本教程适用于J2EE,对于他正在使用EJB 3而言相当过时。1 – tobiasbayer 2012-01-17 12:08:47
BMT是一个非常古老的概念,所以没有理由downvote;)该链接与J2EE相关,但它包含一些代码示例,而一个新的教程没有。带选项2的 – yatskevich 2012-01-17 12:14:03
我发现回答我的问题。如果有人感兴趣,那么这里是[here](http://docs.oracle.com/javaee/6/tutorial/doc/bncij.html)。 – Nurjan 2012-01-20 04:55:15
你的链接和我的答案有区别吗? =) – Marthin 2013-02-25 14:32:08