JPA:处理OptimisticLockException的模式

在(REST)Web服务中处理OLE的正确模式是什么? 这就是我现在正在做的事情,例如,

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(); } } 

无论何时你在代码中看到睡眠,都很有可能是错误的。 有没有更好的方法来处理这个?

另一种方法是立即将故障发送回客户端,但我宁愿不让他们担心。 正确的事情似乎做了使服务器上的请求成功所需的一切,即使它需要一段时间。

谢谢。

如果您获得乐观锁定exception,则意味着某些其他事务已向您尝试更新/删除的实体提交了更改。 由于另一个事务已经提交,因此立即重试可能很有可能成功。

我也会在N次尝试后使方法失败,而不是等待StackOverflowException发生。

静态的“政治正确”答案是返回一个HTTP 409(冲突)女巫与乐观锁定的想法完全匹配。 您的客户应该管理它,可能是几秒钟后重新开始。

我不会在您的应用程序中添加重试的逻辑,因为您的客户端已经处理了返回40X代码的情况。

顺便说一句, catch (InterruptedException e) {}总是一个坏主意,因为系统已经要求你的计算取消,你忽略它。 在Web服务的上下文中, InterruptedException是向客户端发出错误信号的另一个好理由。

如果你只是继续重试,直到它仍然有效,为什么不禁用乐观锁? 您应该让来电者知道他们根据过时的信息做出了决定! 如果您控制双方,则可以返回适当的400代码。 如果它是公开的,那么任意客户只需返回500便可能更友好。(当然,你会使适当的响应代码使用不足!这样的困境)