2010-05-26 61 views
2

我正在處理一個合適的場景。基於C中的條件保護關鍵部分#

我正在使用EntityFramework保存(插入/更新)到多線程環境中的SQL數據庫中。問題是我需要訪問數據庫來查看是否已經創建了一個具有特定鍵的寄存器,以便設置一個字段值(正在執行)或者它是新的以設置不同的值(待定)。這些寄存器由唯一的GUID標識。

我已經通過設置鎖定,因爲我知道實體將不會出現在任何其他工藝,換句話說,我不會有相同的GUID在不同的過程,它似乎是工作的罰款解決了這個問題。它看起來像這樣:

static readonly object LockableObject = new object(); 
static void SaveElement(Entity e) 
{ 
     lock(LockableObject) 
     { 
      Entity e2 = Repository.FindByKey(e); 
      if (e2 != null) 
      { 
       Repository.Insert(e2); 
      } 
      else 
      { 
       Repository.Update(e2); 
      } 
     } 
} 

但這意味着當我有一個巨大的要求被保存的數量,他們將排隊。

我不知道是否有類似的東西(請把它僅僅作爲一個想法):

static void SaveElement(Entity e) 
{ 
     (using ThisWouldBeAClassToProtectBasedOnACondition protector = new ThisWouldBeAClassToProtectBasedOnACondition(e => e.UniqueId) 
     { 
      Entity e2 = Repository.FindByKey(e); 
      if (e2 != null) 
      { 
       Repository.Insert(e2); 
      } 
      else 
      { 
       Repository.Update(e2); 
      } 
     } 
} 

這個想法是有一種保護的受保護基於一個條件,使每個實體Ë會有基於e.UniqueId屬性的自己的鎖。

有什麼想法?

+0

爲什麼不使用數據庫事務或存儲過程? – Ikaso 2010-05-26 16:15:50

回答

0

這可能會爲你工作,你可以鎖定e的實例:

lock(e) 
    { 
     Entity e2 = Repository.FindByKey(e); 
     if (e2 != null) 
     { 
      Repository.Insert(e2); 
     } 
     else 
     { 
      Repository.Update(e2); 
     } 
    } 
+0

這是一個很好的觀點,但我們應該考慮實體e是不穩定的,可能這是行不通的,因爲它會每次鎖定不同的e實例 – NAADEV 2010-06-02 16:36:44

1

不要使用在需要數據庫事務或限制應用程序鎖。

使用的鎖,以防止在數據庫中重複條目是不是一個好主意。它限制了應用程序的可伸縮性,只強制一個實例存在,可以添加或更新這些記錄。或者更糟糕的是,有人最終會嘗試將應用程序擴展到多個進程或服務器,並且會導致數據損壞(因爲鎖對於單個進程是本地的)。

您應該考慮的是在數據庫和事務中使用唯一約束的組合,以確保不會有兩次嘗試添加相同條目都能成功。一個會成功 - 另一個將被迫回滾。

+0

嗯,在訪問數據庫時這並不糟糕,但是...... whatif你正在訪問任何其他共享資源?,即想象知識庫正在訪問一個xml文件或一個循環文件​​。 甚至更​​好,讓我們設想你是不是通過訪問數據庫的工作,但在內存靜態字典訪問... – NAADEV 2010-06-02 16:35:39

+0

難道我們討論併發管理層的EntityFramework,或在一般的併發? EF專門設計用於與數據庫進行交互,因此您將用於管理併發數據操作的策略和技巧應與EF處理數據庫的事實保持一致。如果您需要提供對其他資源(如文件)的併發,可寫訪問權限 - 您不再處理EF - 並且您使用的技術將特定於該特定域。 **併發編程沒有單一的靈丹妙藥。** – LBushkin 2010-06-02 18:42:49

+0

我一直在談論併發性。只是爲了說明,我用EF作爲例子。 – NAADEV 2010-06-07 10:23:21