开发者

Sharing transaction scope between threads

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(TransactionScope开发者_如何学PythonOption.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?


You can take a look at the DependentTransaction class which is useful for transaction across several threads. See the documentation for it.


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.


The problem with your code is that you are not waiting for all the threads to complete their work before you call:

            transaction.Complete();

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜