JPA:处理OptimisticLockException的模式

Jef*_*man 17 java database jpa

在(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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

谢谢.

Aug*_*sto 24

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

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


JB *_*zet 21

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

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