2013-04-04 85 views
7

我正在使用IBM.XMS lib与WebSphereMQ交谈。异步消费者和使用TransactionScope

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

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之内。

有谁知道如何做到这一点?

+0

如果消费者实例已从会话中创建,则会话可能已创建,以便在委托运行期间存在(Transaction.Current)周围的环境事务。 – 2013-04-11 10:26:49

回答

1

由于消息侦听器在与创建TransactionScope的线程不同的线程上运行,消息侦听器(又名异步使用者)不能用于TransactionScope。您只能使用TransactionScope内的同步接收/发送。

This link says“The XA transactions are not supported in asynchronous consumers。”

+0

谢谢!如果下一个版本支持异步使用者的XA事务,那将是非常好的;-) IBM是否有某种uservoice? – 2013-04-16 04:55:32

+0

是的。您可以在https://www.ibm.com/developerworks/rfe/?BRAND_ID=181提交RFE。在此页面上点击“submit RFE”链接。 – Shashi 2013-04-16 05:12:20

+0

很酷,我已经提交了它(http://www.ibm.com/developerworks/rfe/execute?use_case=viewRfe&CR_ID=33621),请将它投票:) – 2013-04-16 06:14:43

1

在使用DependentClone创建DependentTransaction时,可能值得您一边调查。

“一个从属交易是一个交易,其结果取决于它被克隆的交易结果。”

“DependentTransaction是使用DependentClone方法创建的Transaction对象的一个​​克隆,它的唯一目的是允许应用程序停下来并确保事务在事务仍在执行时不能提交(for例如,在工作者线程上)。“

编辑:只是在相关的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(); 
} 
+0

我需要在'TransactionScope'中登记的消息的实际出队,我不明白这将如何解决任何问题! – 2013-04-12 05:37:22

+0

为什么不使用MessageQueueTransaction? http://msdn.microsoft.com/en-us/library/system.messaging.messagequeuetransaction(v=vs.71).aspx – 2013-04-12 07:54:33

+0

'MessageQueueTransaction'与'MessageQueue',MSMQ一起使用。我没有使用MSMQ,我正在使用WebSphereMQ – 2013-04-13 07:19:11