2016-06-09 117 views
1

我为我的.NET应用程序抓取了NuGet包,该包将运行在多个服务器上。对于那些不知道它的人使用SQL Server's application lock functionality来提供一个简单的方法来锁定不同的机器。对于我一直在使用它的很好。但是,我想知道锁定检查的顺序是否会在释放锁定时导致订单被维护。DistributedLock获取订单

例如...可以说我的应用程序正在读队列,然后按顺序处理每个消息。如果每条消息都是关于家庭的,我想要按顺序处理一个家庭的每条消息,会怎么样?遇到的第一条消息可能使用DistributedLock的Acquire来检查帐户是否空闲,如果空闲则锁定它,然后开始处理消息。然后让我们说,队列侦听器应用程序正在另一台服务器上运行,并从同一家庭的队列中读取另一条消息。在这种情况下,Acquire会一直等到住户的锁被释放,然后重新锁定并处理消息。

var myLock = new SystemDistributedLock("UniqueHouseholdIdentifier"); 

using (myLock.Acquire()) 
{ 
    // message processed here in the lock 
} 

但是如果有第三台机器运行相同的应用程序,并且遇到具有相同家庭标识符的消息呢?

因此,机器#1抓住家庭ID为A01的第一条消息,锁定它并开始处理它。机器#2在队列中为A01抓取第二条消息,并等待。机器#3从队列中为A01抓取第三条消息并等待。

在当机#1完成处理这消息A01并释放锁将机#2,该拾起为A01第二消息以上的情况下,前机#3下运行?或者它几乎是随机的,并且机器#2或#3可能获取下一个锁?订单会保留吗?

+0

如果每封邮件都有自己的锁,为什么会有任何订购要求?实际上,为什么你的例子中的收购方会阻止? – usr

回答

1

我提出这个答案与我是DBA,而不是应用程序开发人员(我知道C#足够危险)的警告。

看看你已经链接到的两件事,我不会认为有任何要求的顺序。 sp_getapplock使用与SQL用于锁定行和表之类相同的锁定功能。这只是你正在定义虚拟资源的名称。因此,当一个任务请求通过sp_getapplock锁,将发生以下情况(高级别)

  • 任务进入可运行队列
  • 任务获取到队列的顶部
  • 如果锁没有被另一进程拥有的,你得到它,你就大功告成了
  • 如果锁目前另一个进程拥有,你进入等待状态
  • 当锁被释放时,你的过程被标记为“醒来”,在哪个点上它进入可运行队列(即,回到第一步骤)

的疑难杂症的是,每个调度器具有其自己的可运行队列(即不存在每SQL实例只是一个可运行队列),所以该方法首先获得有非确定性。

如果您正在寻找处理订单,您可能需要查看Service Broker或其他排序技术,包括主题和按顺序交付。

+0

我同意你的看法......我尽可能怀疑,但我想问问。谢谢 – Eves