Rerunning failed Container-Managed transactions in Java EE
I have 开发者_如何学编程a situation with a legacy system which uses Java EE Bean Managed Transactions. It's getting LockAcquisitionException
thrown when it's trying to retrieve something it just created.
My initial thoughts were this:
@TransactionAttribute(SUPPORTS)
public Item retrieveItem(int id) {
Item i;
try {
i = em.find(Item.class, id);
} catch (PersistenceException e) {
if (e.getCause() instanceof LockAcquisitionException) {
i = retrieveItem(id);
}
}
return i;
}
However - when the recursive call is made, the transaction has already died - and it doesn't seem to create a new one. I've tried different TransactionAttributes
, but it doesn't seem to make a difference. Also tried managing the transaction myself (em.getTransaction()
), but that's illegal in CMT.
I'm not looking for an elegant fix - as I said, this is legacy, I just need something that will triage it until the whole thing gets replaced in a couple of months!
Cheers.
Try to annotate retrieveItem
with @TransactionAttribute(REQUIRES_NEW)
: it will then be executed in a new transaction.
Note that:
- the the first was has been invalidated (set for rollback) and will never complete
- during the second transaction, changes done in the first transaction are not visible anyway
So I don't know if it fits your scenario. But it's the only way I know to do an operation and commit it successfully if the original transaction has been invalidated.
Unfortunately the only way I can find to do this is to fix the cause of the transaction - so now I'm doing a em.flush()
at the beginning of retrieveItem()
. Can't wait to replace this app..
精彩评论