2016-06-09 52 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