Hibernate LockModes / LockOptions
我正在浏览Hibernate Documentation并遇到了LockModes
。 这些与我们用于数据库的Isolation levels
相同吗? 它们与Isolation levels
有何不同?
我正在尝试一个简单的例子,并观察到当我使用session.load()方法本身而不是在我在被加载对象上调用某些方法时命中数据库时,hibernate正在访问数据库。
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
我观察到hibernate在第2行本身就遇到了数据库,请告诉我为什么会这样? 如果我删除LockOptions参数,则在Line 3
而不是Line 2
Line 3
进行数据库命中
LockOptions的API很少提供它们的详细信息:
READ表示LockMode.READ(超时+范围不适用)
timeout + scope do not apply
是什么意思?
UPGRADE代表LockMode.UPGRADE(将永远等待锁和范围的假意义只有实体被锁定)
什么时候应该使用UPGRADE? 这意味着scope of false meaning only entity is locked
?
可能这些是有经验的人的基本问题,请帮助我理解这里的概念。
感谢您查看我的post。
隔离级别会影响您所看到的内容。
锁定模式会影响您的操作。
hibernate的正常设置是读取提交隔离和乐观锁定。
使用乐观锁定,当两个人尝试同时编辑相同的数据时,第二个提交将获得exception。
- 用户1在没有升级锁的情况下加载DomesticCat#1066。
- 用户2在没有升级锁的情况下加载DomesticCat#1066。
- 用户2更改了猫的名字并提交。
- 用户1更改了猫的生日,尝试提交,抛出exception。
如果正在使用悲观锁,通过选择LockMode UPGRADE,那么在请求Lock UPGRADE的人释放它之前,将不允许任何其他人改变数据。
- 用户1 使用升级锁加载DomesticCat#1066。
- 用户2在没有升级锁的情况下加载DomesticCat#1066。
- 用户2更改了猫的名字并尝试提交。 在用户1释放锁之前,不允许执行此操作,因此数据库块和用户2的会话处于等待状态。
- 用户1改变了猫的生日,提交。
- 用户2的更新现在可以尝试提交,但由于他们现在使用乐观锁定,他们将是看到exception的人。
在升级时加载时必须立即执行查询的原因是它是使用select ... for update
语句实现的,而hibernate承诺在该方法返回时你将拥有锁,因此它必须执行声明马上。 当你不需要持有锁时,hibernate可能是懒惰的并且推迟加载数据,直到你表明你确实需要它为止。
通常,当您拥有必须完成的操作时,无论其他人在做什么,都会升级锁定级别。 例如,当它是用户时,您可以向他们显示错误,他们可以调整他们的工作并再试一次。 但是,如果消息传递服务器或后台进程正在进行更新,则处理exception并再次尝试可能会非常复杂,因此最好只锁定记录以确保更新进入。
升级意味着您要修改已加载的对象,并且在进行此过程时不希望任何其他进程更改它。
使用UPGRADE加载是一个奇怪的组合,因为加载通常仅用于引用对象以便在修改其他对象时能够使用它。 例如
DomesticCat kitten = (DomesticCat)session.get(DomesticCat.class, 2L); kitten.setParent(d1);
这就是为什么如果你使用一个加载,Hibernate只会在你开始引用属性时加载它。