Java 休眠锁定模式/锁定选项
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21030740/
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
Hibernate LockModes/LockOptions
提问by Chaitanya
I am going through Hibernate Documentation an came across the LockModes
. Are these same as Isolation levels
that we use for database? How are they different from Isolation levels
?
我正在浏览 Hibernate 文档并遇到了LockModes
. 这些和Isolation levels
我们用于数据库的一样吗?他们有什么不同Isolation levels
?
I am trying a simple example and observed that the hibernate is hitting the database when I use session.load() method itself instead of hitting the DB when I call some methods on the loaded object.
我正在尝试一个简单的示例,并观察到当我使用 session.load() 方法本身时休眠正在访问数据库,而不是在我调用加载对象上的某些方法时访问数据库。
session.beginTransaction(); //Line 1
DomesticCat d1 = (DomesticCat)session.load(DomesticCat.class, 1L,LockOptions.UPGRADE); //Line 2
d1.meow(); //Line 3
session.getTransaction().commit(); //Line 4
I observed that hibernate hits the database at line 2 itself, please tell me why it happens like that? If I remove the LockOptions parameter then the DB hit is made on Line 3
instead of Line 2
我观察到 hibernate 在第 2 行本身命中了数据库,请告诉我为什么会这样?如果我删除 LockOptions 参数,那么 DB 命中Line 3
而不是Line 2
The API for LockOptionsgives very little details on what they are:
LockOptions的API提供的细节很少:
READ represents LockMode.READ (timeout + scope do not apply)
READ 代表 LockMode.READ(超时 + 范围不适用)
What does it mean that timeout + scope do not apply
?
这是什么意思timeout + scope do not apply
?
UPGRADE represents LockMode.UPGRADE (will wait forever for lock and scope of false meaning only entity is locked)
UPGRADE 代表 LockMode.UPGRADE(将永远等待锁定和范围为 false 意味着只有实体被锁定)
When we should use UPGRADE? what it means that scope of false meaning only entity is locked
?
什么时候应该使用UPGRADE?这是什么意思scope of false meaning only entity is locked
?
May be these are basic questions for experienced guys, please help me in understanding the concept here.
可能这些是有经验的人的基本问题,请帮助我理解这里的概念。
Thanks for looking my post.
谢谢你看我的帖子。
采纳答案by Affe
Isolation Levels affect what you see.
隔离级别会影响您所看到的内容。
Lock Modes affect what you are allowed to do.
锁定模式会影响您的权限。
The normal settings for hibernate are read-committed isolation and optimistic locks.
休眠的正常设置是读提交隔离和乐观锁。
With optimistic locking, when two people try to edit the same data at the same time, the second one to commit will get an exception.
使用乐观锁,当两个人试图同时编辑相同的数据时,第二个提交的将得到一个异常。
- User 1 loads DomesticCat#1066 without upgrade lock.
- User 2 loads DomesticCat#1066 without upgrade lock.
- User 2 changes cat's name and commits.
- User 1 changes cat's birthday, attempts to commit, an exception is thrown.
- 用户 1 加载了没有升级锁的DomesticCat#1066。
- 用户 2 加载了没有升级锁的DomesticCat#1066。
- 用户 2 更改 cat 的名称并提交。
- 用户 1 更改 cat 的生日,尝试提交,抛出异常。
If pessimistic locks are in use, by selecting LockMode UPGRADE, then nobody else will be allowed to alter the data until the person who asked for the Lock UPGRADE releases it.
如果使用悲观锁,通过选择 LockMode UPGRADE,那么在请求 LockMode UPGRADE 的人释放数据之前,不允许其他人更改数据。
- User 1 loads DomesticCat#1066 withupgrade lock.
- User 2 loads DomesticCat#1066 without upgrade lock.
- User 2 changes cat's name and attempts to commit. This operation is not allowed until User 1 releases the lock, so the database blocks and User 2's session sits and waits.
- User 1 changes cat's birthday, commits.
- User 2's update can now try to commit, but since they used optimistic locking now they will be the one who sees an exception.
- 用户 1 加载带有升级锁的DomesticCat#1066 。
- 用户 2 加载了没有升级锁的DomesticCat#1066。
- 用户 2 更改 cat 的名称并尝试提交。在用户 1 释放锁之前不允许此操作,因此数据库阻塞并且用户 2 的会话坐下并等待。
- 用户 1 更改 cat 的生日,提交。
- 用户 2 的更新现在可以尝试提交,但由于他们现在使用乐观锁定,他们将是看到异常的人。
The reason the query has to be executed as soon as you load when you upgrade is that it's implemented using the select ... for update
statement and hibernate promises you that you'll have the lock when that method returns, so it has to execute the statement right away. When you don't need to hold the lock, hibernate can be lazy and defer loading the data until you show that you actually do need it.
升级时必须在加载后立即执行查询的原因是它是使用select ... for update
语句实现的,并且 hibernate 向您承诺,当该方法返回时,您将获得锁定,因此它必须立即执行该语句。当您不需要持有锁时,hibernate 可以延迟加载数据,直到您证明确实需要它为止。
Generally you upgrade the lock level when you have an operation that mustcomplete regardless of what other people are doing. For example, when it's users, you can just show them the error and they can adjust their work and try again. But if the updates are being made by a messaging server or background process, handling exceptions and trying again can be very complicated, so it might be better to just lock the record so you can be sure your update goes in.
通常,当您的操作必须完成而不管其他人在做什么时,您都会升级锁定级别。例如,当它是用户时,您可以向他们展示错误,他们可以调整他们的工作并重试。但是,如果更新是由消息服务器或后台进程进行的,则处理异常并重试可能会非常复杂,因此最好锁定记录以确保更新进入。
回答by user2987208
UPGRADE means that you want to modify the loaded object and you don't want any other process to change it while you're in the process.
UPGRADE 意味着您想要修改加载的对象,并且您不希望任何其他进程在您处于该进程中时更改它。
It's an odd combination to use load with UPGRADE, because load is generally used just to have reference to the object to be able to use it while modifying some other object. e.g.
将 load 与 UPGRADE 一起使用是一种奇怪的组合,因为 load 通常仅用于引用该对象,以便在修改其他对象时能够使用它。例如
DomesticCat kitten = (DomesticCat)session.get(DomesticCat.class, 2L);
kitten.setParent(d1);
DomesticCat kitten = (DomesticCat)session.get(DomesticCat.class, 2L);
kitten.setParent(d1);
That is why if you use a load, Hibernate will only load it if you start referencing properties.
这就是为什么如果您使用加载,Hibernate 只会在您开始引用属性时加载它。