一尘不染

休眠LockModes / LockOptions

hibernate

我正在通过Hibernate Documentation遇到一个问题LockModes。这些与Isolation levels我们用于数据库的相同吗?它们有何不同Isolation levels

我正在尝试一个简单的示例,并观察到当我使用session.load()方法本身时,hibernate状态正在命中数据库,而不是在加载对象上调用某些方法时,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

LockOptionsAPI几乎没有提供有关它们的详细信息:

READ表示LockMode.READ(超时+范围不适用)

这是什么意思timeout + scope do not apply

UPGRADE表示LockMode.UPGRADE(将永远等待锁定,并且作用域为false意味着只有实体被锁定了)

什么时候应该使用UPGRADE?那是什么意思scope of false meaning only entity is locked

可能这些是有经验的人的基本问题,请在这里帮助我理解概念。

感谢您查看我的帖子。


阅读 281

收藏
2020-06-20

共1个答案

一尘不染

隔离级别会影响您看到的内容。

锁定模式会影响您的操作。

hibernate的正常设置是提交读取的隔离和乐观锁。

使用乐观锁定,当两个人尝试同时编辑同一数据时,第二个提交的人将获得异常。

  1. 用户1加载没有升级锁的DomesticCat#1066。
  2. 用户2加载没有升级锁的DomesticCat#1066。
  3. 用户2更改cat的名称并提交。
  4. 用户1更改猫的生日,尝试提交,抛出异常。

如果使用悲观锁,则通过选择LockMode UPGRADE,将不允许其他任何人更改数据,直到要求Lock UPGRADE的人释放它为止。

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

升级时必须在加载后立即执行查询的原因是,该查询是使用该select ... for update语句实现的,并且Hibernate承诺当该方法返回时您将拥有锁,因此它必须立即执行该语句。当您不需要按住锁时,hibernate状态可能会变得很懒惰,并会延迟加载数据,直到您表明确实需要它为止。

通常,当您具有 必须
完成的操作而不论其他人在做什么时,都可以升级锁定级别。例如,当它是用户时,您可以仅向他们显示错误,他们可以调整其工作并重试。但是,如果更新是由消息传递服务器或后台进程进行的,则处理异常并重试可能会非常复杂,因此仅锁定记录可能会更好,这样可以确保更新得以进行。

2020-06-20