由于悲观锁只能应用于单个数据库事务。并且在用户思考时间内保持数据库事务的打开,以数据库中的锁作为反模式,那么在此之间实现悲观锁的正确方法是什么呢?
我知道如何在长对话中实现乐观锁定与用户思考时间之间,只是不知道如何实现悲观锁定与用户之间的长对话思考时间。
发布于 2019-02-05 11:13:26
简单的回答是,没有这样做的“简单配方”,也没有任何来自Hibernate或任何其他ORM框架的现成解决方案。
长话短说:
您必须弄清楚如何实现一些特性,使应用程序能够为“长对话”模拟数据库锁定行为。
最重要的是确保一旦用户开始使用一条信息(数据库行或一组对象,无论什么适合您的情况),信息不会被任何其他用户使用/操作。此外,您还必须确保在用户完成操作时,或者在经过一定时间之后(您不希望永久锁定您的信息),就有一些发布信息的策略。
因为我不知道你的应用程序的细节,我会给出一个抽象的例子,可以作为你的案例的灵感。当然这不是唯一的解决办法。
请记住,每一步都将包含在一个事务中,因为最终,您的长话将是您的web应用程序中的一系列请求。
另外,假设问题标签中的信息,这个答案的目标是在一个连接到DB的简单web应用程序中找到解决方案。没有“异国情调”建筑。
在需要这种控制的给定表中,添加2列:一个是用户ID,另一个是时间戳。这将控制谁在一行上有一个“锁”,以及它获得的时间。
当用户开始使用表行中包含的数据时,应用程序将使用用户ID和当前日期/时间更新行。--这是最重要的一步,因为必须正确地处理并发。如果不止一个用户试图获取行上的“锁”,您的应用程序必须承认的锁--只有一个用户。此步骤很可能需要在单个事务中使用数据库锁。确保这个步骤是快速的,而不是附加到其他操作,这样数据库锁将不会对您的应用程序有很大的影响。
在用户完成对数据的操作之后,应用程序只需将用户ID和时间戳转换为null,然后其他用户就可以使用它了。
如果用户由于某种原因没有完成任务,则必须应用某种“释放”策略。在简单的情况下,一个简单的时间到期将解决这个问题。如果给定的用户尝试获取已具有锁的行的“锁”,则应用程序将检查时间戳。如果时间戳过期,则新用户将重写该锁。如果没有,则行不可用。
还有其他更复杂的情况。如果在您的过程中,在操作完全完成之前在数据库中更改了信息(假设用户进行了各种信息更改,并将它们发送到DB,在用户完成操作并“释放”行之前),那么您可能需要弄清楚如何实现回滚。也许让数据“半途而废”是可以的,也许不是,这取决于您的业务需求。
长话短说:
如果其中任何一个建议适用于您的场景,请仔细考虑。
希望这能帮上忙。
https://stackoverflow.com/questions/54530557
复制相似问题