Java 我需要什么 Hibernate LockMode 来读取和更新对象,同时防止其他人这样做?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18777031/
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
What Hibernate LockMode do I need to read and update an object while preventing others from doing so?
提问by f1dave
In the following code sample:
在以下代码示例中:
Session session = getSessionFactory().openSession();
MyObject currentState = (MyObject)
session.get(MyObject.class, id, new LockOptions(LockMode.???));
if (!statusToUpdateTo.equals(currentState.getStatus())) {
tx = session.beginTransaction();
currentState.setStatus(statusToUpdateTo);
session.save(currentState);
tx.commit();
}
session.close();
As you might hopefully interpret from the code, the idea is to check our store and find an object with a given id, then update it to a given status. If we find that the object is already in the status we want to update to, we abandon doing anything. Otherwise, we update the status and save it back to the store.
正如您可能希望从代码中解释的那样,我们的想法是检查我们的商店并找到具有给定 id 的对象,然后将其更新为给定状态。如果我们发现对象已经处于我们想要更新的状态,我们就放弃做任何事情。否则,我们更新状态并将其保存回商店。
The worry I've got is that what if several of these requests come through at once, and all try to read and update the same object? Looking through the doco it would seem like Hibernate "usually obtains exactly the right lock level automatically." (LockMode.class) but I'm still keen to ensure that only one thing can read the object, make the decision that it needs to update it, and then update it - without any other threads doing the same to the same database entry.
我担心的是,如果这些请求中的几个同时通过,并且都尝试读取和更新同一个对象怎么办?通过 doco 看起来,Hibernate“通常会自动获得完全正确的锁定级别”。(LockMode.class) 但我仍然热衷于确保只有一件事可以读取对象,决定它需要更新它,然后更新它 - 没有任何其他线程对同一个数据库条目做同样的事情。
From the LockMode class I thinkPESSIMISTIC_WRITE is what I'm after, but can't seem to find a documentation resource that confirms this. Is anyone able to confirm this for me, and that the above code will do what I'm after?
从 LockMode 类,我认为PESSIMISTIC_WRITE 是我所追求的,但似乎无法找到证实这一点的文档资源。有没有人能够为我确认这一点,并且上面的代码会做我想要的?
采纳答案by f1dave
So I noticed in my original code that upon session close, a lock was still left on the database, as subsequent calls to delete the rows I'd inserted didn't complete when tx.commit() was called on them.
所以我在我的原始代码中注意到,在会话关闭时,数据库上仍然保留了一个锁,因为在对它们调用 tx.commit() 时,随后删除我插入的行的调用没有完成。
After adding the following else block, my tests pass which I infer as meaning the lock has been released (as these rows are now being cleaned up).
添加以下 else 块后,我的测试通过,我推断这意味着锁已被释放(因为这些行现在正在被清理)。
Session session = getSessionFactory().openSession();
MyObject currentState = (MyObject)
session.get(MyObject.class, id,
new LockOptions(LockMode.PESSIMISTIC_WRITE));
if (!statusToUpdateTo.equals(currentState.getStatus())) {
tx = session.beginTransaction();
currentState.setStatus(statusToUpdateTo);
session.save(currentState);
tx.commit();
} else {
// Seems to clear lock
tx = session.beginTransaction();
tx.rollback();
}
session.close();
To me, this obviously reflects my lack of understanding about Hibernate's locking mechanisms, but it does seem slightly strange that one can get a lock using session.get(...) or session.load(...) and then not release a lock using session itself, but rather only through creating a transaction and committing/rolling back.
对我来说,这显然反映了我对 Hibernate 的锁定机制缺乏了解,但使用 session.get(...) 或 session.load(...) 获得锁定然后不释放一个似乎有点奇怪使用会话本身锁定,而只能通过创建事务和提交/回滚。
Of course, I could just be misunderstanding the observed behaviour :)
当然,我可能只是误解了观察到的行为:)