异步消费者和使用TransactionScope

7
我将使用IBM.XMS库与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 中。

有人知道如何做吗?


如果消费者实例是从会话创建的,则可能已经创建了一个环绕(Transaction.Current)的环境事务,以便在委托运行期间存在。 - Simon Mourier
2个回答

1
这个建议值得考虑,使用DependentClone创建一个DependentTransaction
“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();
}

我需要将消息的实际出队列列入“TransactionScope”,我不知道这样做会解决什么问题! - John Simons
为什么你不使用 MessageQueueTransaction?http://msdn.microsoft.com/zh-cn/library/system.messaging.messagequeuetransaction(v=vs.71).aspx - Paul Zahra
MessageQueueTransaction 用于 MessageQueue,即 MSMQ。我没有使用 MSMQ,而是使用 WebSphereMQ。 - John Simons
啊,我的错了...你看过https://dev59.com/yk7Sa4cB1Zd3GeqP4pFk吗? - Paul Zahra

1
一个消息监听器,也称为异步消费者,不能在TransactionScope中使用,因为消息监听器运行在与创建TransactionScope的线程不同的线程上。您只能在TransactionScope中使用同步接收/发送。
这个link说:“异步消费者不支持XA事务。”

谢谢!如果下一个版本支持异步消费者的XA事务,那将非常好;-) IBM有某种用户反馈平台吗? - John Simons
是的。您可以在https://www.ibm.com/developerworks/rfe/?BRAND_ID=181提交RFE。一旦打开此页面,请单击“提交RFE”链接。 - Shashi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接