問題描述
我正在嘗試像在 SQL Server 中嵌套事務一樣嵌套事務范圍 (.net 4.0),但它們的操作方式似乎不同.我希望我的子事務在失敗時能夠回滾,但允許父事務決定是否提交/回滾整個操作.問題是當第一次完成時,事務被回滾.我意識到完成與提交不同.
I am trying to nest TransactionScopes (.net 4.0) as you would nest Transactions in SQL Server, however it looks like they operate differently. I want my child transactions to be able to rollback if they fail, but allow the parent transaction to decide whether to commit/rollback the whole operation. The problem is when the first complete occurs, the transaction is rolled back. I realize that complete is different to commit.
我正在嘗試做的一個大大簡化的例子:
A greatly simplified example of what I am trying to do:
static void Main(string[] args)
{
using(var scope = new TransactionScope()) // Trn A
{
// Insert Data A
DoWork(true);
DoWork(false);
// Rollback or Commit
}
}
// This class is a few layers down
static void DoWork(bool fail)
{
using(var scope = new TransactionScope()) // Trn B
{
// Update Data A
if(!fail)
{
scope.Complete();
}
}
}
我不能使用 Suppress 或 RequiresNew 選項,因為 Trn B 依賴于 Trn A 插入的數據.如果我使用這些選項,Trn B 會被 Trn A 阻止.
I can't use the Suppress or RequiresNew options as Trn B relies on data inserted by Trn A. If I do use those options, Trn B is blocked by Trn A.
任何想法如何讓它工作,或者甚至可以使用 System.Transactions 命名空間?
Any ideas how I would get it to work, or if it is even possible using the System.Transactions namespace?
謝謝
推薦答案
您可能不會喜歡這個答案,但是...
You're probably not going to like this answer, but...
在嵌套范圍內投票
雖然嵌套作用域可以加入根作用域的環境事務,但是在嵌套作用域中調用Complete對根作用域沒有影響.只有從根作用域到最后一個嵌套作用域的所有作用域都投票提交事務,才會提交事務.
Although a nested scope can join the ambient transaction of the root scope, calling Complete in the nested scope has no affect on the root scope. Only if all the scopes from the root scope down to the last nested scope vote to commit the transaction, will the transaction be committed.
(來自 使用事務范圍實施隱式事務)
TransactionScope
類很遺憾沒有提供任何機制(據我所知)來隔離工作單元.要么全有要么全無.您可以使用 TransactionScopeOption.Suppress
來防止在特定工作單元上發生任何 事務,但這可能不是您想要的,因為您將失去原子性在那個范圍內.
The TransactionScope
class unfortunately doesn't provide any mechanism (that I know of) for segregating units of work. It's all or nothing. You can prevent any transaction from occurring on a specific unit of work by using TransactionScopeOption.Suppress
, but that is probably not what you want, as you would then lose atomicity for whatever is inside that scope.
只有一種環境"使用 TransactionScope
時的交易.一旦 TransactionScope
在沒有執行 Complete
的情況下被釋放或收集,整個環境事務將被回滾;就這樣,游戲結束.
There is only one "ambient" transaction when you use a TransactionScope
. Once a TransactionScope
is disposed or gets collected without Complete
being executed, the whole ambient transaction gets rolled back; that's it, game over.
事實上,SQL Server 根本不支持真正的嵌套事務,盡管 有可能(盡管有些不直觀)通過適當使用 SAVE TRAN
語句.如果您需要此特定行為,則將此邏輯重新實現為存儲過程(或其中幾個)可能是您的最佳選擇.
In fact, SQL Server doesn't support true nested transactions at all, although it is possible (though somewhat unintuitive) to achieve the same end result with appropriate use of SAVE TRAN
statements. Re-implementing this logic as a Stored Procedure (or several of them) might be your best option if you require this particular behaviour.
這篇關于嵌套/子事務范圍回滾的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!