Async Consumer和TransactionScope的使用

时间:2013-04-04 03:25:16

标签: c# ibm-mq

我正在使用IBM.XMS lib与WebSphereMQ交谈。

使用同步方法接收消息时,例如:

using (var scope = new TransactionScope(TransactionScopeOption.Required, transactionOptions))
{
       message = consumer.Receive(1000);

       if (message != null)
       {
            //Do work here
            scope.Complete();
       }
}

但是如果我想使用异步方法:

consumer.MessageListener = delegate(IMessage msg)
{
    //Do work here
    //But where do I put TransactionScope?
};

我无法弄清楚如何在MessageListener内包装TransactionScope回调。

有谁知道怎么做?

2 个答案:

答案 0 :(得分:1)

使用DependentClone调查DependentTransaction进行调查可能值得您这么做。

“依赖事务是一种事务,其结果取决于克隆它的事务的结果。”

“DependentTransaction是使用DependentClone方法创建的Transaction对象的克隆。它的唯一目的是允许应用程序休息并保证在事务上仍在执行工作时事务无法提交(例如,在工人线程上。“

编辑:刚刚在相关的SO问题列表中发现了这一点:related question and answer查看他们提供的msdn链接:非常值得阅读Managing Concurrency with DependentTransaction

取自上面的MSDN链接(为简洁起见):

public class WorkerThread
{
    public void DoWork(DependentTransaction dependentTransaction)
    {
        Thread thread = new Thread(ThreadMethod);
        thread.Start(dependentTransaction); 
    }

    public void ThreadMethod(object transaction) 
    { 
        DependentTransaction dependentTransaction = transaction as DependentTransaction;
        Debug.Assert(dependentTransaction != null);

        try
        {
            using(TransactionScope ts = new TransactionScope(dependentTransaction))
            {
                /* Perform transactional work here */ 
                ts.Complete();
            }
        }
        finally
        {
            dependentTransaction.Complete(); 
            dependentTransaction.Dispose(); 
        }
    }

//Client code 
using(TransactionScope scope = new TransactionScope())
{
    Transaction currentTransaction = Transaction.Current;
    DependentTransaction dependentTransaction;    
    dependentTransaction = currentTransaction.DependentClone(DependentCloneOption.BlockCommitUntilComplete);
    WorkerThread workerThread = new WorkerThread();
    workerThread.DoWork(dependentTransaction);

    /* Do some transactional work here, then: */
    scope.Complete();
}

答案 1 :(得分:1)

消息侦听器a.k.a Asynchronous Consumer不能在TransactionScope中使用,因为消息侦听器在与创建TransactionScope的线程不同的线程上运行。您只能在TransactionScope内使用同步接收/发送。

link表示“异步使用者不支持XA事务。”