EJB/Hibernate事务触发回滚-但不会还原来自DB的更改
在EJB中的一个方法中,我希望回滚事务,并在其中一个更新失败时恢复所有数据。EJB/Hibernate事务触发回滚-但不会还原来自DB的更改,hibernate,jakarta-ee,transactions,ejb,rollback,Hibernate,Jakarta Ee,Transactions,Ejb,Rollback,在EJB中的一个方法中,我希望回滚事务,并在其中一个更新失败时恢复所有数据。 其思想是,当objectB的更新失败时,我还希望恢复objectA的更新 在异常处理块中,我用ejbContext.setRollbackOnly()标记了事务但objectA的状态未回滚 使用update操作进行测试,情况相同 下面是我想做的事情的简短复制: @Stateless public class Bean1 { @PersistenceContext protected EntityMan
其思想是,当objectB的更新失败时,我还希望恢复objectA的更新 在异常处理块中,我用
ejbContext.setRollbackOnly()标记了事务代码>但objectA的状态未回滚
使用update
操作进行测试,情况相同
下面是我想做的事情的简短复制:
@Stateless
public class Bean1 {
@PersistenceContext
protected EntityManager em;
@Resource
protected EJBContext ejbContext;
@TransactionAttribute(TransactionAttributeType.REQUIRED)
@Override
public void deleteObjects(A objectA, B objectB) {
try {
// try to remove the ObjectA
if (!em.contains(objectA)) {
objectA= em.merge(objectA);
}
em.remove(objectA);
// try to remove the ObjectB
if (!em.contains(objectB)) {
objectB= em.merge(objectB);
}
em.remove(objectB);
/*
At this step the objectA is removed and the state is flushed to DB
and erased from DB but; when is trying to remove the objectB
an ConstraintViolationException is thrown and the object
is not removed.
*/
em.flush();
} catch (Exception ex) {
// here I mark the transaction for rollback, but the objectA is
// definitively removed from DB
ejbContext.setRollbackOnly();
throw ex;
}
}
}
我在persistence.xml文件中有以下Hibernate配置:
重要的
另外,如果我删除em.flush()
,则不会回滚objectA。解释是,当方法被执行(完成)时,事务将被提交,最初objectA会自动刷新,而当尝试刷新objectB时,会引发异常
[更新1]
我已经意识到事务是回滚的,但传播到DB的更改不会恢复。
同样,对于这段代码,回滚并不是还原DB中的写入值
... // the same code as before
try {
objectA.setField1("new value");
em.merge(objectA);
//after this step the changes are in DB
em.flush();
// mark to rollback the transaction
// after this line the transaction is relledback and closed
// but the changes stay with the new values in DB
ejbContext.setRollbackOnly();
} catch (Exception ex) {...
[更新2]
通过研究,我发现MyApplication正在更改MySql配置(AUTOCOMMIT
),设置为setautocommit=1
,这意味着如果我在MySql中执行一个查询,该查询是自动提交的。使用entityManager.flush()
所有查询都在mySql中执行,我的假设是每次启动新事务时,我的应用程序都应该设置AUTOCOMMIT=1
。我说得对吗?是否有针对这种行为设计的hibernate配置
欢迎任何建议 您的上下文类型是JTA还是ResourceLocal??您的代码的行为就像声明为ResourceLocal….@CarlitosWay我用我的persistence.xml
文件配置更新了这个问题。应为JTA配置。回滚是否由异常触发?由于您只指定了catch(Exception ex)
,我想知道:这是一个自定义的异常吗?如果是,是否对其进行了注释?如果您使用的是wildfy或jboss,请从持久性中删除有关刷新的属性。xml ans还将删除提供程序节点。。。然后再试一次…不。。。如果您计划让服务器(EJB)来处理事务边界,那么必须避免像您所说的那样的配置(设置autocommit=1)。。。你怎么做这样的配置??
Hibernate: 4.3.10.Final
... // the same code as before
try {
objectA.setField1("new value");
em.merge(objectA);
//after this step the changes are in DB
em.flush();
// mark to rollback the transaction
// after this line the transaction is relledback and closed
// but the changes stay with the new values in DB
ejbContext.setRollbackOnly();
} catch (Exception ex) {...