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. 用户1在没有升级锁的情况下加载DomesticCat#1066。
  2. 用户2在没有升级锁的情况下加载DomesticCat#1066。
  3. 用户2更改了猫的名字并提交。
  4. 用户1更改了猫的生日,尝试提交,抛出exception。

如果正在使用悲观锁,通过选择LockMode UPGRADE,那么在请求Lock UPGRADE的人释放它之前,将不允许任何其他人改变数据。

  1. 用户1 使用升级锁加载DomesticCat#1066。
  2. 用户2在没有升级锁的情况下加载DomesticCat#1066。
  3. 用户2更改了猫的名字并尝试提交。 在用户1释放锁之前,不允许执行此操作,因此数据库块和用户2的会话处于等待状态。
  4. 用户1改变了猫的生日,提交。
  5. 用户2的更新现在可以尝试提交,但由于他们现在使用乐观锁定,他们将是看到exception的人。

在升级时加载时必须立即执行查询的原因是它是使用select ... for update语句实现的,而hibernate承诺在该方法返回时你将拥有锁,因此它必须执行声明马上。 当你不需要持有锁时,hibernate可能是懒惰的并且推迟加载数据,直到你表明你确实需要它为止。

通常,当您拥有必须完成的操作时,无论其他人在做什么,都会升级锁定级别。 例如,当它是用户时,您可以向他们显示错误,他们可以调整他们的工作并再试一次。 但是,如果消息传递服务器或后台进程正在进行更新,则处理exception并再次尝试可能会非常复杂,因此最好只锁定记录以确保更新进入。

升级意味着您要修改已加载的对象,并且在进行此过程时不希望任何其他进程更改它。

使用UPGRADE加载是一个奇怪的组合,因为加载通常仅用于引用对象以便在修改其他对象时能够使用它。 例如

DomesticCat kitten = (DomesticCat)session.get(DomesticCat.class, 2L); kitten.setParent(d1);

这就是为什么如果你使用一个加载,Hibernate只会在你开始引用属性时加载它。