开发者

How to retry a lock wait timeout using java persistence?

I need some clarification on the right way to retry a "retryable" exception (e.g. 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/开发者_如何学Ccommit 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.)


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜