0

我正在研究通過IOC從第三方數據驅動程序加載的插件。插件和數據驅動程序都在相同的SQL Server 2005數據庫上運行,但該插件專注於與數據驅動程序管理的表具有外鍵關係的一小部分表。如何在SqlTransaction中的實體框架3.5中執行更新

我的問題是,在某些操作中,數據驅動程序正在創建一個圍繞調用我的插件的SQLTransaction,這導致我的操作失敗(超時異常)。一個典型的場景如下的僞碼/代碼路徑:

DataDriver.InsertEntity(IBusinessObject businessObject) 
{ 
    CreateSqlTransaction(); 
    AddEntityToEntityTable(businessObject); 
    Plugin.PersistAdditionalData(businessObject); 
    CommitOrRollbackTransaction(); 
} 

在我的插件,我在做這樣的事情:

Plugin.PersistAdditionalData(IBusinessObject businessObject) 
{ 
    var dbObject = GetObjectFromDatabase(businessObject); // Via Entity Framework 
    var additionalData = CreateAdditionalDataObject(businessObject); 

    // Insert data to a table with a foreign key relationship to a table that the 
    // data driver has just inserted the business object data to in the current 
    // transaction. 
    _entityModel.AddToObject_AdditionalData_AssociationSet(additionalData); 
    _entityModel.SaveChanges();   
} 

我已經試過包裝我的方法在使用( TransactionScope){...}塊,但一直沒有能夠得到這個工作。它確實將失敗從讀取(GetObjectFromDatabase)移動到保存。

我無權訪問數據驅動程序代碼或任何有關事務已提交或回滾的通知。如果我知道要建議什麼,我可能有可能讓開發人員進行一些更改,但我更喜歡不需要這樣的解決方案。

回答

1

這只是猜測......

數據驅動程序正在使用比你的插件不同的SQL連接。因此,您的代碼運行在不同的事務中(或沒有),並與數據驅動程序發生的未被改變的更改衝突,從而導致死鎖。

的解決思路:

  • 使您的代碼使用相同的連接,數據驅動器。這需要連接以某種方式提供給插件。而且你需要一種方法來讓實體模型使用它(從來沒有與我自己的實體模型一起工作)。這將是最好的解決方案。你的東西會自動參與交易,所有的好結果如一致性等。
  • 嘗試確保兩個連接在同一個事務中運行。這在理論上可以使用System.Transactions。這也需要調整數據驅動程序以使用System.Transactions型號。我懷疑這兩個連接會以這種方式看到對方的變化,所以這可能不會起作用。
  • 請勿使用交易。您可能會指示數據庫服務器忽略事務,因此不需要更改數據驅動程序。這會工作。當然,交易是由於某種原因發明的...

我會去第一個。瞭解如何告訴實體模型使用特定的sql連接,然後讓數據驅動程序開發人員將其提供給您。這甚至可能導致更好的性能,因爲需要更少的連接。

+0

這些都是正確的,但不幸的是我不能使用你的任何建議,因爲他們需要修改調用數據驅動程序。 – Todd 2010-10-13 19:32:29