我有一个班级做一些交易代码 让我们假设:
class Worker
{
public void doWork()
{
//I do not want to create a new transaction. Instead, i want to use the environmenttransaction used by the caller of this method
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required)) {
workItem1();
workItem2();
workItem3();
scope.Complete();
}
}
现在我有一些执行此代码的线程:
Worker worker = new Worker();
using (TransactionScope transaction = new TransactionScope())
{
Thread Thread1 = new Thread(new ThreadStart(worker.doWork));
Thread1.Start();
Thread Thread2 = new Thread(new ThreadStart(worker.doWork));
Thread2.Start();
Thread Thread3 = new Thread(new ThreadStart(worker.doWork));
Thread3.Start();
Thread.Sleep(10000); //this should be enough to all the workers finish their job
transaction.Complete();
}
每个线程都在创建自己的事务。我如何在所有线程之间共享相同的事务?
答案 0 :(得分:6)
您可以查看DependentTransaction
类,它对多个线程的事务很有用。请参阅documentation。
答案 1 :(得分:1)
您拥有的代码将创建竞争条件。在线程完成之前,您几乎会立即调用scope.complete。
然而,即使每个工作者都创建了一个事务范围,如果创建了一个新事务范围,这些实际上也会被.Net嵌套到顶级事务范围。
如果您想要嵌套分层事务,那么您可能希望使用ScopeOption.RequiresNew
创建新范围。但这是一个真实问题的答案,这就是你想要这样做的原因。交易固有地意味着您的工作在某种程度上是顺序的或关键的,以某种顺序发生。如果你可以并行完成工作,那么尽可能尝试在单独的事务中进行,将范围限制在尽可能短的时间内,以防止锁定等。
答案 2 :(得分:-3)
您的代码存在的问题是您在打电话之前没有等待所有线程完成工作:
transaction.Complete();
因此,在多线程事务作为原子事务完成之前,任何线程都可以调用此方法。您可能需要使用Semaphore类来避免冲突。
另外,如果您的环境允许,我会考虑使用PLinq。