根据这篇 MSDN 文章,您应该能够对一个进程进行多线程处理,每个线程都登记在一个根事务中。
我根据那篇文章创建了一个示例,我希望在其中回滚事务(bool[] results
应该全部false
在foreach
循环中)。不幸的是,情况并非如此,结果是可以预见的(运行示例足够多次,您将看到bool
数组中的任何值组合)。
此外,我已经尝试了这两种方法DependentCloneOption.BlockCommitUntilComplete
,但都DependentCloneOption.RollbackIfNotComplete
没有产生预期的结果。
其次,我认为ThreadPool.QueueUserWorkItem
充其量是丑陋的代码,很高兴看到这样的东西Parallel.ForEach
改为使用。
最后,我的问题:) 为什么这不起作用?我究竟做错了什么?在单个事务中包装多个线程是完全不可能的吗?
namespace Playing
{
class Program
{
static bool[] results = new bool[] { false, false, false };
static void Main(string[] args)
{
try
{
using (var outer = new TransactionScope(
TransactionScopeOption.Required))
{
for (var i = 0; i < 3; i++ )
{
ThreadPool.QueueUserWorkItem(WorkerItem,
new Tuple<int, object>(
i, Transaction.Current.DependentClone(
DependentCloneOption.BlockCommitUntilComplete)));
}
outer.Complete();
}
}
catch { /* Suppress exceptions */ }
// Expect all to be false
foreach (var r in results)
Console.WriteLine(r);
}
private static void WorkerItem(object state)
{
var tup = (Tuple<int, object>)state;
var i = tup.Item1;
var dependent = (DependentTransaction)tup.Item2;
using (var inner = new TransactionScope(dependent))
{
// Intentionally throw exception to force roll-back
if (i == 2)
throw new Exception();
results[i] = true;
inner.Complete();
}
dependent.Complete();
}
}
}