2012-09-26 52 views
1

我正在將網站移至多個實例。這意味着我不能再使用lock以確保服務不會在其上運行。所以我需要一種方法來鎖定實例。將SQL Server數據庫事務用作C#鎖

我應該使用與消息隊列後臺工作,但我覺得這是矯枉過正這一項服務。我想知道如果我能以某種方式使用數據庫事務作爲鎖。我不在乎速度 - 我想讓它變得簡單&工作。

這裏就是我想這樣做的:

public class MultiInstanceLock : IDisposable 
{ 
    private readonly string lockId; 
    private Transaction transaction; 
    private LockEntity lockEntity; 

    public MultiInstanceLock(String _lockId) 
    { 
     lockId = _lockId; 

     transaction = new Transaction(IsolationLevel.RepeatableRead, lockId); 
     lockEntity = new LockEntity(lockId); 
     if(lockEntity.IsNew) 
      lockEntity.Id = lockId; 

     lockEntity.LockedOn = DateTime.Now; 
     lockEntity.Save(); 
    } 

    public void Dispose() 
    { 
     if (lockEntity != null) 
     { 
      lockEntity.UnlockedOn = DateTime.Now; 
      lockEntity.Save(); 
     } 

     if(transaction != null) 
      transaction.Commit(); 
    } 
} 

這裏的用法:

using(var l = new MultiInstanceLock("Foo")) 
{ 
    ...do foo... 
} 

將這項工作?有沒有更好的辦法?

已經我注意到,這項交易將適用於我的using語句,這是一個令人失望內部的任何數據庫訪問。

回答

1

看一看SQL服務器applocks-正是你需要(試圖鎖定一個命名的資源)。

http://msdn.microsoft.com/en-us/library/ms189823.aspx

我們寫了一個小IDisposable的包裝解決此進行採集和清理更加容易。

+0

謝謝馬特 - 你有什麼機會分享你的包裝? – bendytree

+0

對不起,我們的包裝被捆綁到一堆我無法發佈的內部基礎架構中。下面是類似的,一些鏈接,但:http://interlace.googlecode.com/svn-history/r38/trunk/source/library/Interlace/DatabaseManagement/DatabaseLock.cs – nitzmahone

+0

繼馬特的意見,我創造了'sp_getapplock的一個簡單的包裝'&它完美的作品:http://pastie.org/4811362 – bendytree