在线程之间共享事务范围
我有一堂课正在做一些事务代码。
让我们假设:
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();
}
每个线程都在创建一个自己的事务。我如何在所有线程之间共享相同的事务?
I have one class doing some transactional code.
Lets assume:
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();
}
}
Now i have some threads that execute this code:
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();
}
Each thread is creating an own transaction. How do i do the share the same transaction between all threads?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以查看 DependentTransaction 类,它对于跨多个线程的事务非常有用。请参阅文档为了它。
You can take a look at the
DependentTransaction
class which is useful for transaction across several threads. See the documentation for it.您拥有的代码将创建竞争条件。在线程完成之前,您几乎会立即调用scope.complete。
然而,即使每个工作人员创建一个事务范围,如果创建了一个新的事务范围,这些实际上也被 .Net 嵌套到顶级事务范围。
如果您想要有一个嵌套的分层事务,那么您可能需要使用 ScopeOption.RequiresNew 创建新范围。但这是对一个真正问题的回答,这就是您想要这样做的原因。事务本质上意味着您的工作在某种程度上是连续的或按特定顺序发生的至关重要。如果您可以并行工作,那么请尽可能在单独的事务中完成它,将范围限制在尽可能短的时间内,以防止被锁定等。
The code you have will create a race condition. You will almost immediately call scope.complete before your threads finish.
However even though each worker creates a transaction scope, these are actually nested by .Net to the top level transaction scope, if a new one is created at all.
If you want to have a nested layered transaction then you might want to create the new scope with
ScopeOption.RequiresNew
. But this is answer to a real question, which is why you would want to do this. Transactions inherently mean your work is in some way sequential or critical to have happen in a certain order. If you can parallel up the work, then try to do it in separate transactions wherever possible, limit the scope to the shortest possible amount of time to prevent locks being taken etc.您的代码的问题在于,您在调用之前没有等待所有线程完成其工作:
因此,您的任何线程都可以在多线程事务作为原子事务完成之前调用此方法。您可能需要使用 Semaphore 类来避免冲突。
另外,如果您的环境允许,我会考虑使用 PLinq。
The problem with your code is that you are not waiting for all the threads to complete their work before you call:
So any of your threads can call this method before your multithreaded transaction completes as an atomic one. You'd probably need to use the Semaphore class to avoid the collision.
Also, i would look into using PLinq if your environment allows for it.