2009-10-08 108 views
0

在單個事務中使用企業庫數據訪問塊處理批處理的一系列CRUD操作的最佳實踐是什麼,它不會被分散到分佈式事務?企業庫數據訪問塊事務管理最佳實踐

編輯全部來源:

public void BatchInsertEvents(IList<EventItem> events) 
{ 
    _dataAccessBase = new DataAccessBase("[dbo].[EventInsert]"); 
    int count = 0; 

    try 
    { 
     using (var scope = 
        new TransactionScope(TransactionScopeOption.RequiresNew)) 
     { 
      foreach (var eventItem in events) 
      { 
       _dataAccessBase.ClearParameters(); 

       _dataAccessBase.AddInParameter("@time", 
              DbType.String, eventItem.Time); 
       ...more params 

       _dataAccessBase.ExecuteNonQuery(); 
       count++; 
      } 

      scope.Complete(); 
     } 
} 

我DataAccessBase僅僅是數據庫對象的包裝類

public class DataAccessBase 
{ 
    private readonly DbCommand _command; 
    private readonly Database _database; 

    public DataAccessBase(string storedProcName) : this(null, storedProcName) 
    { 
    } 

    public DataAccessBase(string connectionString, string storedProcName) 
    { 
     _database = string.IsNullOrEmpty(connectionString) ? 
        DatabaseFactory.CreateDatabase() : 
        DatabaseFactory.CreateDatabase(connectionString); 
     _command = _database.GetStoredProcCommand(storedProcName); 
    } 

    public void AddInParameter<T>(string parameterName, 
              DbType parameterType, T value) 
    { 
     _database.AddInParameter(_command, 
           parameterName, parameterType, value); 
    } 


    public void AddOutParameter<T>(string parameterName, 
           DbType parameterType, int parameterLength) 
    { 
     _database.AddOutParameter(_command, 
           parameterName, parameterType, parameterLength); 
    } 

    public void ClearParameters() 
    { 
     _command.Parameters.Clear(); 
    } 

    public void ExecuteNonQuery() 
    { 
     _database.ExecuteNonQuery(_command); 
    } 
} 
+0

這絕對不是這樣,因爲我的代碼在我的開發機器上工作正常,但我們託管的prod數據庫已關閉DTC,因此它肯定成爲分佈式事務。 – 2009-10-08 20:47:12

+0

我想我們可能需要查看'DataAccessBase.ExecuteNonQuery'中的代碼來調試。 – 2009-10-12 14:42:40

+0

我的意思是包括那一個,我沒有意識到我剔除了它,但這是一個微不足道的方法,爲了清楚起見,我添加了它。 – 2009-10-12 15:48:16

回答

1

我猜測發生了什麼事是,你使用的EntLib與連接池。

然後會發生的事情是,您得到的事務分散在多個連接上。然後這會升級爲分佈式事務。

Entlib非常擅長的一件事是關閉連接。你需要編寫你的代碼,以便重複使用單個連接。

一些這在這個環節上解釋:http://msdn.microsoft.com/en-us/library/cc511672.aspx

如果仍然有問題,內發佈您的代碼爲每個循環。

EDIT

嘗試移動線:

_dataAccessBase = new DataAccessBase("[dbo].[EventInsert]"); 

事務範圍內。

EDIT 2

你能也動_dataAccessBase申報的交易範圍

DataAccessBase _dataAccessBase = new DataAccessBase("[dbo].[EventInsert]"); 

內這只是爲了確保該連接不交易範圍之外使用。

+0

我查看了您的鏈接並更改了我的交易範圍聲明,但它仍將其升級爲分佈式交易。我包括了我用於解決問題的完整源代碼。 – 2009-10-12 13:57:59

+0

在範圍內移動,仍然是MSDTC未啓用,因此它肯定是一個分佈式事務相同的錯誤 – 2009-10-12 16:06:55

+0

Your DataAccessBase(string connectionString,string storedProcName)有兩個參數,但你用一個參數調用它,你可以發佈碼。此代碼是否從它被調用的代碼的任何外部事務作用域中運行? – 2009-10-12 16:34:38

0

編輯:發佈後,我意識到我幾乎完全重複了設拉子Bhaiji給出的建議。請忽略。

第二次嘗試:

請爲DatabaseFactory.CreateDatabase提供的代碼()。偶然有一個額外的TransactionScope嗎?如果是這樣,並且您使用相同的TransactionScopeOption.RequiresNew,則可以輕鬆升級到DTC。

+0

DatabaseFactory.CreateDatabase()是企業庫的代碼,我應該可以運行它通過反射器,看看它是否創建一個交易範圍內 – 2009-10-18 16:51:32

+0

我試圖在反射器analzye這個代碼然而,因爲它實際上是推理依賴注入我不知道在哪裏確切的代碼建立數據庫,看看它是否初始化事務範圍在裏面它的某個地方。不過,我也使用過。不僅需要RequiresNew,如果它已經存在,應該使用環境事務,但它也沒有做任何不同的事情。 – 2009-10-19 13:01:00

+0

先生,最後的完整代碼在哪裏?謝謝 – Kiquenet 2010-07-20 16:39:19