简体   繁体   中英

How to retry a lock wait timeout using java persistence?

I need some clarification on the right way to retry a "retryable" exception (eg something like lock wait timeout) when using java persistence. For example, with pseudocode like:

EntityTransaction tx = em.getTransaction();
tx.begin();
for (a bunch of objects) {
  em.persist(object);
}
tx.commit();

I sometimes get an exception thrown at the em.persist call if there's a lock in the db. Can I just wrap that in a try/catch and retry it (with some count, obviously)? Or do I have to wrap the whole tx.begin/commit and redo that ?

thx

Assuming that the lock timeouts are not there as a workaround for database deadlocks, a simpler solution would be to just use longer time-outs on your requests. Instead of using an N second timeout and retrying up to C times, set the timeout to N * (C + 1) seconds.

(If you are using the lock timeouts as a workaround for deadlocks, then you have a bigger problem. You'd do better to try to fix the root cause of the deadlocks, because even with C retries there is a probability that your transactions won't go through.)

So long as the exception thrown by the EntityManager does not mark the transaction as rollback only (LockTimeoutException is one such example, however PessimisticLockException is not) you can continue to process things in the current transaction.

If the TX gets marked as rollback only, you'll have to bail out the TX, then retry anything that you attempted -before- the error occurred within the TX and continue along.

If you're going gobs of things in a loop with JPA, chances are you have a good candidate for a DELETE or UPDATE jpql query.

If you are programming to the spec, you are actually supposed to dispose the entire EntityManager and start over. There are no exceptions that are guaranteed to be 'retryable' at the EM level. Your entire persistence session is considered inconsistent/indeterminate if an exception comes out of the persist() method.

Sometimes it will work. I know in hibernate you can usually get away with trying gain after an optimistic lock exception. But in general, you are relying on vendor specific behavior that may be poorly defined if you try to catch and recover from entitymanager exceptions and keep the same entitymanager.

More info here.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM