2009-11-10 31 views
4

即使拋出異常並且最外層的作用域從未提交過調用,在什麼情況下代碼可以封裝在System.Transactions.TransactionScope仍然提交?儘管System.Transactions.TransactionScope.Commit()未調用,但數據已提交

using (var tx = new TransactionScope())中有一個頂級方法,它以同樣的方式調用也使用TransactionScope的方法。

我正在使用帶有關聯表適配器的類型化數據集。難道是因爲某種原因,適配器中的命令不能使用嗎?你們中的任何人都知道如何檢查他們是否參與了環境TransactionScope?

+0

是否存在嵌套事務? – 2009-11-10 12:28:02

+0

那麼,TransactionScope是嵌套的,是的。在'using(var tx = new TransactionScope())'中包含一個頂級方法,並調用也使用TransactionScope的方法。 – 2009-11-10 12:30:59

+0

這是什麼數據庫? – 2009-11-10 16:04:35

回答

7

答案竟然是因爲我創建了TransactionScope對象SqlConnection對象。

我從這個感動:

using (new ConnectionScope()) 
using (var transaction = new TransactionScope()) 
{ 
    // Do something that modifies data 

    transaction.Complete(); 
} 

這樣:

using (var transaction = new TransactionScope()) 
using (new ConnectionScope()) 
{ 
    // Do something that modifies data 

    transaction.Complete(); 
} 

和現在的作品!

因此,故事的寓意是創建您的TransactionScope第一個

+2

它也顯示發佈代碼的價值;-p我們可能已經發現了它;沒關係 - 現在排序。 – 2009-11-10 16:53:34

+1

是的,但在這種情況下,我無法做到這一點,因爲該應用程序太複雜,我沒有在一個小例子中複製它。 – 2009-11-10 17:18:14

+4

我認爲你可以先創建SqlConnection(如果你需要將它傳遞給所有使用TransactionScope的方法,在已經有連接並想創建一個事務範圍的情況下,你可以調用connection.ElistTransaction (Transaction.Current)在範圍的使用塊內 – Triynko 2010-05-21 17:35:02

2

顯而易見的情況是明確指定了新的(RequiresNew)/ null(Suppress)事務 - 但也存在可能導致連接錯過事務的超時/解除綁定故障。看到這個earlier post(修復只是一個連接字符串的變化),或full details

+0

在研究我的問題時,我嘗試了更早的連接字符串更改,但在這種情況下沒有幫助。我想我可能在某處有'RequiresNew',所以我來看看。 – 2009-11-10 14:04:00

+0

我正在使用與相關的表適配器類型的數據集。難道是因爲某種原因,適配器中的命令不能使用嗎?你知道如何檢查他們是否參與了環境TransactionScope嗎? – 2009-11-10 15:03:14

+0

我最終找到了答案 - 處理事務範圍和連接對象的創建順序。我已將我的回答添加到此帖子。 – 2009-11-10 16:17:07

0

要知道如何TransactionScope作品:
它在使用範圍的開頭設置屬性System.Transactions.Transaction.Current,然後將其設置回以前的值在使用範圍的結束。

上一個值取決於聲明給定範圍的位置。它可以在另一個範圍內。


您可以修改代碼:

using (var sqlConnection = new ConnectionScope()) 
using (var transaction = new TransactionScope()) 
{ 
    sqlConnection.EnlistTransaction(System.Transactions.Transaction.Current); 
    // Do something that modifies data 
    transaction.Complete(); 
} 

我表明這種可能性爲那些誰擁有自己的代碼比較複雜,不能簡單地改變代碼首先打開數據庫連接。

相關問題