What is the correct pattern for handling OLE in a (REST) web service? this is what I'm doing now, for example,
protected void doDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ... ... ... try { try { em.getTransaction().begin(); // ... remove the entity em.getTransaction().commit(); } catch (RollbackException e) { if (e.getCause() instanceof OptimisticLockException) { try { CLog.e("optimistic lock exception, waiting to retry ..."); Thread.sleep(1000); } catch (InterruptedException ex) { } doDelete(request, response); return; } } // ... write response } catch (NoResultException e) { response.sendError(HttpServletResponse.SC_NOT_FOUND, e.getMessage()); return; } finally { em.close(); } }
anytime you see a sleep in the code, there's a good chance it's incorrect. Is there a better way to handle this?
another approach would be to immediately send the failure back to the client, but I'd rather not have them worry about it. the correct thing seems to do whatever is required to make the request succeed on the server, even if it takes a while.
Solution. To resolve this error we have two ways: Get the latest object from the database and set the old object values if you need those values to be persisted to the new object and merge it. For the old object set the latest version from Database.
In order to use optimistic locking, we need to have an entity including a property with @Version annotation. While using it, each transaction that reads data holds the value of the version property. Before the transaction wants to make an update, it checks the version property again.
public class OptimisticLockException extends PersistenceException. Thrown by the persistence provider when an optimistic locking conflict occurs. This exception may be thrown as part of an API call, a flush or at commit time. The current transaction, if one is active, will be marked for rollback.
If you get an optimistic locking exception, it means that some other transaction has committed changes to entities you were trying to update/delete. Since the other transaction has committed, retrying immediately might have a good chance to succeed.
I would also make the method fail after N attempts, rather than waiting for a StackOverflowException to happen.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With