以hibernate为例,如何在与用户之间的长对话中实现悲观锁定?

以hibernate为例,如何在与用户之间的长对话中实现悲观锁定?,hibernate,web-applications,pessimistic-locking,Hibernate,Web Applications,Pessimistic Locking,因为悲观锁只能应用于单个数据库事务。并在用户思考时间内保持数据库事务打开,将数据库中持有的锁视为反模式,那么在用户思考时间之间实现悲观锁的正确方法是什么 我知道如何在与用户的长时间对话中实现乐观锁定,只是不知道如何在与用户的长时间对话中实现悲观锁定。简单的回答是,没有“简单的方法”可以做到这一点,也没有任何来自Hibernate或任何其他ORM框架的现成解决方案 答案很长: 您必须弄清楚如何实现一些特性,使您的应用程序能够模拟“长对话”中的数据库锁定行为 最重要的是确保一旦用户开始使用一条信息(

因为悲观锁只能应用于单个数据库事务。并在用户思考时间内保持数据库事务打开,将数据库中持有的锁视为反模式,那么在用户思考时间之间实现悲观锁的正确方法是什么


我知道如何在与用户的长时间对话中实现乐观锁定,只是不知道如何在与用户的长时间对话中实现悲观锁定。

简单的回答是,没有“简单的方法”可以做到这一点,也没有任何来自Hibernate或任何其他ORM框架的现成解决方案

答案很长:

您必须弄清楚如何实现一些特性,使您的应用程序能够模拟“长对话”中的数据库锁定行为

最重要的是确保一旦用户开始使用一条信息(数据库行或一组对象,无论什么适合您的情况),该信息不会被任何其他用户使用/操纵。此外,您还必须确保在用户完成操作时或经过一定时间后(您不希望信息被永久锁定)发布信息时有一些策略

由于我不知道你的应用程序的细节,我将给出一个抽象的例子,可能会对你的案例有所启发。当然,这不是唯一的解决办法

请记住,每个步骤都将包含在一个事务中,因为最终,您的长对话将是web应用程序中的一系列请求

此外,假设来自问题标签的信息,这个答案的目标是在一个连接到DB的简单web应用程序中找到一个解决方案。没有“奇特的”建筑

在需要这种控制的给定表中,添加两列:一列是用户ID,另一列是时间戳。这将控制谁拥有一行上的“锁”,以及获取该行的时间


当用户开始使用表行中包含的数据时,您的应用程序将使用用户ID和当前日期/时间更新该行这是最重要的一步,因为您必须正确处理并发问题。如果有多个用户试图获取行上的“锁”,则您的应用程序必须仅为一个用户让出锁。此步骤很可能需要在单个事务中使用数据库锁。确保此步骤快速且不附加到其他操作,以便数据库锁定不会对应用程序产生太大影响

用户完成数据操作后,应用程序可以简单地将用户ID和时间戳设置为null,然后其他用户就可以使用它了

如果用户由于某种原因没有完成任务,则必须应用某种“发布”策略。在简单的情况下,一个简单的时间到期将解决这个问题。如果给定用户尝试在已经有锁的行上获取“锁”,您的应用程序将检查时间戳。如果时间戳过期,新用户将覆盖锁。如果不是,则该行不可用

还有其他更复杂的情况。如果在您的过程中,在操作完全完成之前数据库中的信息发生了更改(假设用户进行了各种信息更改,并在用户完成操作并“释放”行之前将其发送到数据库),那么您可能需要弄清楚如何实现回滚。也许让数据“半操纵”是可以的,也许不是,这取决于您的业务需要

长话短说:

  • 锁由数据库表中的列组成
  • 您的代码控制锁

  • 用户试图获取锁

  • 若行是空闲的,或者上一个锁已过期,则获取锁
  • 操作完成后,锁被擦除
仔细考虑这些建议是否适用于您的场景


我希望这是有帮助的

“此步骤很可能需要在单个事务中使用数据库锁”,此步骤是哪个步骤?“当用户开始使用表行中包含的数据时,您的应用程序将使用用户ID和当前日期/时间更新该行。”-获取锁步骤。