我得到了由包含者管理的會話bean。最近,我遇到的問題,在這裏拋出異常:EJB:CMT,拋出後如何重試操作
org.hibernate.StaleObjectStateException:行被其它事務更新或刪除(或者未保存值的映射是不正確的)
這是因爲一些其他進程已經更新行(和版本字段已更改)。現在,當它被拋出時,我抓住OptimisticLockException並希望重新運行失敗的操作(我想把WRITE鎖這段時間,以確保它不會再次失敗),我做這種方式:
T ctj = new T();
C ca = entityManager.find(C.class, id);
Double newBalance = Operations.add(ca.getAccountBalance(), amount);
ca.setAccountBalance(newBalance);
entityManager.persist(ca);
ctj.setBalanceAfterTransaction(newBalance);
entityManager.persist(ctj);
try {
flushRegisterTransactionUpdateAccountBalance();
} catch(OptimisticLockException ex) {
retryBalanceUpdate(ca, ctj, amount);
}
我呼籲在上面的方法:
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
private void retryBalanceUpdate(C ca, T ctj, Double amount) {
entityManager.refresh(ca);
entityManager.lock(ca, LockModeType.WRITE);
Double newBalance = Operations.add(ca.getAccountBalance(), amount);
ca.setAccountBalance(newBalance);
entityManager.persist(ca);
ctj.setBalanceAfterTransaction(newBalance);
entityManager.persist(ctj);
flushRegisterTransactionUpdateAccountBalance();
}
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
private void flushRegisterTransactionUpdateAccountBalance() {
entityManager.flush();
}
這些2種方法我都裝箱,因爲我希望是因爲()由flushRegisterTransactionUpdateAccountBalance拋出的異常的整個(父)交易不會失敗。
不幸的是失敗,當我在catch塊方法retryBalanceUpdate調用,它的第一行的機身(entityManager.refresh(CA))拋出:
[TxPolicy] javax.ejb.EJBTransactionRolledbackException:EntityManager的必須訪問在一個事務中 [爲myBean]無交易 javax.persistence.TransactionRequiredException:EntityManager的必須是在一個事務中訪問
是否anybode知道我怎麼能實現我解釋?我使用的是EJB 3.0,entityManager對象是由類級註釋啓動的:
@PersistenceContext(unitName =「MyPersistenceUnit」)private EntityManager entityManager;
類它的自我是無狀態會話bean與交易屬性支持