寻找有关分布式系统中记录锁定的建议

时间:2023-01-25 06:58:43

We're trying to come up with a recommended design pattern for our team when it comes to record locking. The typical school of thought goes something like this: 1. User picks a record from a list 2. Lock the record with the user id 3. Load the locked record record (no lock, then someone beat ya to it).

在记录锁定方面,我们正试图为我们的团队提出推荐的设计模式。典型的思想流派是这样的:1。用户从列表中选择一条记录2.用用户ID锁定记录3.加载锁定的记录记录(没有锁定,然后有人打败它)。

Am I missing something, or does this appear to be the only way to do this? ((In our case Optimistic locking would prove cumbersome and confusing for the end users. Edits are often quite substantial.))

我错过了什么,或者这似乎是唯一的方法吗? ((在我们的案例中,乐观锁定对于最终用户来说会很麻烦和困惑。编辑通常非常重要。))

1 个解决方案

#1


2  

The detail that could make your solution administration intensive is getting rid of locks after crashes or connectivity failures. That's where the tradeoff between optimistic and pessimistic locking really lies. Manually merging, or redoing, edits when optimistic locking fails is a pain, but mopping up after crashes on pessimistic and persistent locking models creates its own headaches (as anyone who supported users of Pervasive backed accounting systems in the 90s will tell you at length given the opportunity)

可能使您的解决方案管理密集的细节是在崩溃或连接失败后摆脱锁定。这就是乐观和悲观锁定之间的权衡取舍。在乐观锁定失败时手动合并或重做编辑是一件痛苦的事情,但在悲观和持久锁定模型崩溃之后扫荡会产生自己的麻烦(因为任何支持90年代Pervasive支持会计系统用户的人都会告诉你详细信息机会)

One answer is to use your RDBMS's mechanisms for managing transactions and concurrency: Grab the record with SELECT FOR UPDATE or whatever syntax your suits your environment and isolation level. If one of your clients crashes or gets disconnected the transaction rolls back and the lock gets released.

一个答案是使用您的RDBMS管理事务和并发的机制:使用SELECT FOR UPDATE或适合您的环境和隔离级别的任何语法来获取记录。如果您的某个客户端崩溃或断开连接,则事务将回滚并锁定被释放。

In a connectionless environment like the web or an environment where connections get lost and recovered frequently a session based model with a session timeout could also work:

在Web等连接环境或连接丢失和频繁恢复的环境中,具有会话超时的基于会话的模型也可以工作:

  • Attempt to clear the existing lock on the record if it is for an expired session
  • 如果是过期会话,则尝试清除记录上的现有锁定

  • Attempt to lock the record to the sessionid (Fails if the previous step failed)
  • 尝试将记录锁定到sessionid(如果上一步失败,则会失败)

  • Select the locked record (No record returned if the previous step failed)
  • 选择锁定记录(如果上一步失败,则不返回记录)

So the lock gets released when the session expires. No having to manually remove locks after crashes and some tolerance of client/connectivity problems. It does take a bit more work to code though.

因此,当会话到期时锁会被释放。崩溃后无需手动删除锁定以及客户端/连接问题的一些容忍度。尽管如此,编码确实需要做更多的工作。

#1


2  

The detail that could make your solution administration intensive is getting rid of locks after crashes or connectivity failures. That's where the tradeoff between optimistic and pessimistic locking really lies. Manually merging, or redoing, edits when optimistic locking fails is a pain, but mopping up after crashes on pessimistic and persistent locking models creates its own headaches (as anyone who supported users of Pervasive backed accounting systems in the 90s will tell you at length given the opportunity)

可能使您的解决方案管理密集的细节是在崩溃或连接失败后摆脱锁定。这就是乐观和悲观锁定之间的权衡取舍。在乐观锁定失败时手动合并或重做编辑是一件痛苦的事情,但在悲观和持久锁定模型崩溃之后扫荡会产生自己的麻烦(因为任何支持90年代Pervasive支持会计系统用户的人都会告诉你详细信息机会)

One answer is to use your RDBMS's mechanisms for managing transactions and concurrency: Grab the record with SELECT FOR UPDATE or whatever syntax your suits your environment and isolation level. If one of your clients crashes or gets disconnected the transaction rolls back and the lock gets released.

一个答案是使用您的RDBMS管理事务和并发的机制:使用SELECT FOR UPDATE或适合您的环境和隔离级别的任何语法来获取记录。如果您的某个客户端崩溃或断开连接,则事务将回滚并锁定被释放。

In a connectionless environment like the web or an environment where connections get lost and recovered frequently a session based model with a session timeout could also work:

在Web等连接环境或连接丢失和频繁恢复的环境中,具有会话超时的基于会话的模型也可以工作:

  • Attempt to clear the existing lock on the record if it is for an expired session
  • 如果是过期会话,则尝试清除记录上的现有锁定

  • Attempt to lock the record to the sessionid (Fails if the previous step failed)
  • 尝试将记录锁定到sessionid(如果上一步失败,则会失败)

  • Select the locked record (No record returned if the previous step failed)
  • 选择锁定记录(如果上一步失败,则不返回记录)

So the lock gets released when the session expires. No having to manually remove locks after crashes and some tolerance of client/connectivity problems. It does take a bit more work to code though.

因此,当会话到期时锁会被释放。崩溃后无需手动删除锁定以及客户端/连接问题的一些容忍度。尽管如此,编码确实需要做更多的工作。