我有一个应用程序,我想将多个数据库保存到一个事务中。如果他们中的任何一个失败了,我想把整个事情都回滚。但是,我想在回滚事务之前知道其中哪些失败(或成功)。
我有一个带有内部循环的外部 TransactionScope,其中循环的每次迭代都有自己的 TransactionScope。我想运行所有这些并找出哪些失败了。
例如,如果我有 5 件东西我想尝试保存,但第 1 件和第 3 件都失败了,我想知道这一点。这要求我尝试所有 5 次保存,如果一个失败,则将整个东西回滚,但只有在所有 5 次都尝试过之后。
我看到的是,在第一个失败的事务之后,所有后续使用 TransactionScope 都会立即抛出他们自己的 TransactionAbortedException 并且不让我尝试保存以查看它是否有效。
这是一个例子:
using (var scope = new System.Transactions.TransactionScope(TransactionScopeOption.Required, new TransactionOptions() { IsolationLevel = System.Transactions.IsolationLevel.RepeatableRead}, EnterpriseServicesInteropOption.Full))
{
var outputStatus = new List<string>();
for (int i = 0 ; i < 5 ; i++)
{
try
{
using (var innerScope = new System.Transactions.TransactionScope(TransactionScopeOption.Required, new TransactionOptions() { IsolationLevel = System.Transactions.IsolationLevel.RepeatableRead}, EnterpriseServicesInteropOption.Full))
{
// Do work here that causes an exception on first iteration only
if (i == 0)
{
throw new Exception(string.Format("Iteration {0} has FAILED", i));
}
else
{
outputStatus.Add("SUCCESS");
}
}
}
catch (Exception e)
{
outputStatus.Add("ERROR, " + e.Message);
}
}
// Print out outputStatus values here
}
在这段代码的末尾, outputStatus 集合如下所示:
- 错误,迭代 0 已失败
- 错误,事务已中止。
- 错误,事务已中止。
- 错误,事务已中止。
- 错误,事务已中止。
在第一个异常之后,其余的都无法到达succeed 语句。
有没有办法在外部事务范围内运行所有内部事务并允许我控制外部事务范围的回滚?
更新:
在此示例模拟的实际代码中,我无法更改包含内部 TransactionScope 的代码。它在我无法控制的物体中。因此,我正在寻找的解决方案需要能够处理内部事务抛出异常。