Java JPA:处理 OptimisticLockException 的模式
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6541628/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JPA: pattern for handling OptimisticLockException
提问by Jeffrey Blattman
what is the correct pattern for handling OLE in a (REST) web service? this is what i'm doing now, for example,
在 (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();
}
}
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.
另一种方法是立即将故障发送回客户端,但我不想让他们担心。正确的做法似乎是做任何使请求在服务器上成功所需的事情,即使需要一段时间。
thanks.
谢谢。
采纳答案by JB Nizet
If you get an optimistic locking exception, it means that some other transaction has committedchanges 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.
我也会在 N 次尝试后使该方法失败,而不是等待 StackOverflowException 发生。
回答by Augusto
The "politically correct" answer in rest, is to return an HTTP 409 (Conflict) witch matches perfectly with the idea of optimistic locking. Your client should manage it, probably by retring a few seconds later.
其余的“正确”答案是返回一个与乐观锁定的想法完美匹配的 HTTP 409(冲突)女巫。您的客户应该管理它,可能是在几秒钟后重试。
I wouldn't add the logic to retry in your app, as your client will already handle situations when you return a 40X code.
我不会在您的应用程序中添加重试逻辑,因为当您返回 40X 代码时,您的客户端已经处理了这种情况。
回答by Affe
If you're just going to keep retrying until it works anyway, why not just disable optimistic locking? You should let the caller know that they made a decision based on out dated information! If you're in control of both sides an appropriate 400 code can be returned. If it's public it can be more friendly to arbitrary clients to just return 500. (Of course then you perpetuate the under-use of appropriate response codes! such a dilemma)
如果您只想继续重试直到它正常工作,为什么不禁用乐观锁定?您应该让来电者知道他们根据过时的信息做出了决定!如果您控制双方,则可以返回适当的 400 代码。如果它是公开的,它可以对任意客户端更友好,只返回 500。(当然,你会继续使用适当的响应代码!这样的困境)
回答by Jason Penney
By the way, catch (InterruptedException e) {}
is always a bad idea, because the system has asked your computation to cancel, and you are ignoring it. In the context of a web service, an InterruptedException
would be another good reason to signal an error to the client.
顺便说一句,catch (InterruptedException e) {}
这总是一个坏主意,因为系统要求您取消计算,而您却忽略了它。在 Web 服务的上下文中,InterruptedException
向客户端发出错误信号是另一个很好的理由。