代码之家  ›  专栏  ›  技术社区  ›  Zé Carlos

线程间共享事务作用域

  •  2
  • Zé Carlos  · 技术社区  · 14 年前

    我有一个类在做一些事务代码。

    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();
    }  
    

    3 回复  |  直到 8 年前
        1
  •  6
  •   Kit    7 年前

    你可以看看 DependentTransaction 类,该类对于跨多个线程的事务非常有用。看到了吗 documentation 为了它。

        2
  •  1
  •   Spence    14 年前

    但是,即使每个工作进程都创建了一个事务作用域,如果创建了一个新的事务作用域,它们实际上也是由.Net嵌套到顶级事务作用域的。

    如果您想要有一个嵌套的分层事务,那么您可能想要用 ScopeOption.RequiresNew . 但这是一个真正问题的答案,这就是为什么你会想这样做。事务本质上意味着您的工作在某种程度上是连续的或关键的,以一定的顺序发生。如果您可以并行工作,那么尽可能在单独的事务中进行,将范围限制在尽可能短的时间内,以防止锁被占用等。

        3
  •  -3
  •   dexter    14 年前

    代码的问题在于,在调用之前,您没有等待所有线程完成它们的工作:

                transaction.Complete();
    

    因此,任何线程都可以在多线程事务作为原子事务完成之前调用此方法。您可能需要使用Semaphore类来避免冲突。