我有以下 ejb:
for (int i = 1; i <= shopItem.getQuantity(); i++) {
purchase = new Purchase();
purchase.setUser(user);
// a lot of sets
purchase.setPhoneNumber(order.getPhoneNumber());
try {
financeEntityEjb.createPurchase(purchase);
} catch (NotEnoughFundsException e) {
throw new NotEnoughFundsExceptionWithRollback(e); // Making in rollable
}
}
public void createPurchase(Purchase purchase) throws InputValidationException, NotEnoughFundsException {
// a lot of calculations
em.persist(purchase);
em.flush();
/* Closing Order */
purchase.getOrder().setState(Order.State.PURCHASED);
em.merge(purchase.getOrder());
}
我的异常类:
@ApplicationException(rollback = true)
public class NotEnoughFundsExceptionWithRollback extends NotEnoughFundsException {
public NotEnoughFundsExceptionWithRollback() {
}
public NotEnoughFundsExceptionWithRollback(Throwable e) {
super(e);
}
public NotEnoughFundsExceptionWithRollback(String message, Throwable e) {
super(message, e);
}
}
所以我遇到了 ejb 回滚所有 em.persist(purchase); 的问题但忽略 em.merge(purchase.getOrder());
UPD:循环位于purchaseEjb 中。 CreatePurchase 方法位于 FinanceEjb 上
最佳答案
我假设 for 循环中的代码不在 ejb 内(您没有使用 this
)。在这种情况下,问题很可能如下
EJB 中容器管理的事务最后一次方法调用。根据事务属性,它会忽略、启动或加入事务。
默认值为必需,这意味着事务在调用 createPurchase
时开始,并在该方法完成时结束(通常是
代理会注意这一点)。
当使用 @ApplicationException(rollback = true)
抛出应用程序异常时,或者当发生 RuntimeException
时,事务将回滚
set-rollback-only-flag 已设置。
在您的情况下,这些情况很可能都不会发生在 createPurchase
的事务上下文中。您没有显示 NotEnoughFundsException
的代码,但是
我假设它没有用 @ApplicationException(rollback = true)
注释。
相反,您已注释了 NotEnoughFundsExceptionWithRollback
,它是由调用 EJB 的客户端抛出到事务上下文之外的。
如果您希望整个循环成为原子操作,则需要将其放置在事务上下文中(例如,使用 EJB)
关于Java EE 事务回滚,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38503772/