Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何实现脱机读写器锁定_C#_Database_Algorithm_Domain Driven Design - Fatal编程技术网

C# 如何实现脱机读写器锁定

C# 如何实现脱机读写器锁定,c#,database,algorithm,domain-driven-design,C#,Database,Algorithm,Domain Driven Design,问题的背景 这个问题中的所有对象都是持久的 所有请求都将来自Silverlight客户端,通过二进制协议(Hessian)与应用服务器对话,而不是WCF 每个用户都有一个会话密钥(不是ASP.NET会话),它是字符串、整数或GUID(目前尚未确定) 有些对象可能需要很长时间才能编辑(30分钟或更长时间),因此我们决定使用悲观脱机锁定。悲观是因为必须协调冲突对用户来说太烦人了,脱机是因为客户端没有永久连接到服务器 我没有将会话/对象锁定信息存储在对象本身中,而是决定任何可能锁定其实例的聚合根都

问题的背景

  • 这个问题中的所有对象都是持久的
  • 所有请求都将来自Silverlight客户端,通过二进制协议(Hessian)与应用服务器对话,而不是WCF
  • 每个用户都有一个会话密钥(不是ASP.NET会话),它是字符串、整数或GUID(目前尚未确定)
有些对象可能需要很长时间才能编辑(30分钟或更长时间),因此我们决定使用悲观脱机锁定。悲观是因为必须协调冲突对用户来说太烦人了,脱机是因为客户端没有永久连接到服务器

我没有将会话/对象锁定信息存储在对象本身中,而是决定任何可能锁定其实例的聚合根都应该实现一个接口ILockable

public interface ILockable
{
  Guid LockID { get; }
}
这个LockID将是一个“Lock”对象的标识,该对象保存正在锁定它的会话的信息

现在,如果这是简单的悲观锁定,我就能够非常简单地实现这一点(在锁上使用递增的版本号来识别更新冲突),但我真正需要的是ReaderWriter悲观离线锁定

原因是应用程序的某些部分将执行读取这些复杂结构的操作。这些包括

  • 读取单个结构以克隆它
  • 读取多个结构以创建二进制文件,从而将数据“发布”到外部源
读锁将被保持很短的时间,通常不到一秒钟,尽管在某些情况下,它们可能被保持大约5秒钟

写锁大部分会被持有很长一段时间,因为它们大部分由人类持有

两个用户试图同时编辑同一聚合的可能性很高,许多用户也很可能同时需要临时读取锁。我正在寻找关于如何实现这一点的建议

另外一点需要说明的是,如果我想放置一个写锁,并且有一些读锁,我希望将写锁“排队”,这样就不会放置新的读锁。如果读取锁在X秒内被移除,则获得写入锁,否则写入锁将退出;写入锁排队时不会放置新的读取锁

到目前为止,我有这个想法

  • 锁对象将有一个版本号(int),这样我可以检测多个更新冲突,重新加载,然后重试
  • 它将有一个用于读取锁的字符串[]
  • 用于保存具有写锁的会话ID的字符串
  • 用于保存排队写入锁的字符串
  • 可能是一个递归计数器,允许同一会话多次锁定(对于读锁和写锁),但还不能确定这一点
  • 规则:

    • 如果存在写入锁或排队写入锁,则无法放置读取锁
    • 如果存在写入锁或排队写入锁,则无法放置写入锁
    • 如果根本没有锁,则可以放置写锁
    • 如果存在读锁,则写入锁将排队,而不是放置完整的写锁。(如果在X时间后读取锁未消失,则锁将退出,否则将升级)
    • 无法对具有读锁的会话的写锁排队
    有人看到什么问题吗?建议替代方案?任何东西在决定采取何种方法之前,我希望得到反馈。

    您是否考虑过实施:

    诚然,这将更难实现,但似乎比您所解释的要并行得多。只是把想法抛在脑后。

    (编辑后的措辞更像是一个答案,而不是一堆问题)

    我在Yahoo DDD列表上也回答了这个问题,但为了完整起见,我也可能在这里回答

    您没有明确提到(我可以看到)任何类型的写锁超时。我知道他们可以被关押很长时间,但有一个谨慎的策略是暂停(即使有通知)

    禁止(甚至是那样),如果您还没有考虑过的话,您可能想考虑有一种方法来手动释放锁——这取决于系统的用户/角色,也许是某种易于使用的管理界面。


    另外,您无疑也想到了这一点,请确保读锁数组是线程安全的。

    如果您真的希望自己进行锁定,我将遵循类似于线程锁定的锁定模式,例如ReaderWriterLockSlim中的锁定模式


    在这种情况下,这不是一种可接受的方法,谢谢:-)它不需要是线程安全的,因为所讨论的对象是持久的,将加载到单独的对象空间中。我只需要在更新时检查冲突。至于暂停。工作线程将检查超时并释放锁。