JPA:处理 OptimisticLockException 的模式

2022-09-01 13:55:05

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

每当您在代码中看到睡眠时,很有可能它是不正确的。有没有更好的方法来解决这个问题?

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


答案 1

如果收到乐观锁定异常,则表示某些其他事务已将更改提交到您尝试更新/删除的实体。由于其他事务已提交,因此立即重试可能会很有可能成功。

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


答案 2

其余“政治正确”的答案是返回HTTP 409(冲突)女巫与乐观锁定的想法完美匹配。您的客户应该管理它,可能是在几秒钟后重试。

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


推荐