如何在一个PHP/MySQL的Web应用中实现悲观锁定?

6
如何在php/mysql web应用程序中实现悲观锁定?
  1. Web用户打开一个页面以编辑一条数据集(行)
  2. Web用户点击“锁定”按钮,因此其他用户可以读取但无法写入此数据集
  3. Web用户进行一些修改(可能需要1到30分钟)
  4. Web用户单击“保存”或“取消”并删除“锁定”
在php/mysql中是否有标准方法来处理这种情况? 如果Web用户从未单击“保存”/“取消”而关闭Internet Explorer会发生什么?
3个回答

10

你需要在你的表中实现LOCKDATE和LOCKWHO字段。我在PHP/Mysql之外的许多应用程序中都这样做。

当TTL过期时,锁定将被终止,因此您可以使用NOW和LOCKDATE进行日期减法运算,以查看对象是否已被锁定超过30分钟或1小时,视情况而定。

另一个要考虑的因素是当前用户是否锁定了对象。所以你还需要一个LOCKWHO。这可以是你数据库中的user_id, PHP的session_id。但请确保它标识了一个用户,IP地址不是一种好的方法。

最后,始终考虑一个批量解锁功能,简单地重置所有的LOCKDATEs和LOCKWHOs...

干杯


1
请注意,乐观锁也是一种很好的工作方式,您可以使用一个简单的LASTUPDATE列来实现乐观锁,并将其与隐藏字段中的最后一个LASTUPDATE值进行比较。如果数据已更改,则强制用户接受他必须重新启动编辑,或者您可以尝试并查看是否要执行MERGE页面以显示用户比较新旧内容。 - Mathieu Dumoulin
我正在考虑与上述LOCKDATE和LOCKWHO非常相似的东西。您是否曾考虑过在用户编辑时使用jQuery / Ajax请求来更新LOCKDATE字段(从编辑视图)? - jjwdesign
我不会实现一个jQuery锁更新器,因为如果由于任何原因,您的用户忘记关闭浏览器并且有人需要编辑对象,则它将永远不会超时。给您的锁定日期设置合理的TTL确实是最佳选择的方法。 - Mathieu Dumoulin
需要自己编写代码来实现 Web 应用程序中的悲观锁定,不能使用现有框架中的某些简单函数调用吗? - user1169587
我相信你可以找到一个框架,它要么本身就有这个功能,要么通过插件实现。但考虑到这是在2013年编写的,你可能需要重新审视锁定的必要性。今天一般应用程序的行为是使用ReST模式,它们并不适合悲观锁定,也许在某些程度上适合乐观锁定,但不适合悲观锁定。 - Mathieu Dumoulin

7
我建议将锁定信息写入一个集中的表格,而不是在所有表格中添加字段。
例如,可以创建一个名为“tblLocks”的表格,包含以下字段:
  • TableName(被锁定的表格名称)
  • RowID(被锁定的行的主键)
  • LockDateTime(锁定时间)
  • LockUser(锁定用户)
采用这种方法,您可以查找特定用户所做的所有锁定,而无需扫描所有表格。例如,当用户注销时,您可以终止所有锁定。

6
传统上,这是通过在数据库记录上使用布尔类型的locked列进行标记来完成的。
这种锁定的功能需要释放锁定,但情况可能会阻止自然释放(系统崩溃、用户愚蠢、丢失网络数据包等等)。这就是为什么您需要提供一些手动解锁方法和/或对记录可以被锁定多长时间施加时间限制(也许使用cron job?)。如果浏览器仍然打开,您可以实现某种AJAX轮询来保持记录被锁定?无论如何,在修改记录之前,最好验证记录中的数据与获取锁时相同。
这种行为的局限性在Web应用程序中特别普遍,但适用于使用此方法的任何内容 - Sage Line 50是其中之一,我经常不得不在机器/应用程序崩溃后删除锁定文件。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接