生产环境中的transactionScope和ServiceBus存在问题

时间:2014-10-10 11:23:46

标签: c# entity-framework transactionscope unit-of-work servicebus

我见过其他类似问题,但我还没有找到合适的解决方案。

我在调用Database和ServiceBus时使用了一个事务。

我正在为我的数据库使用UnitOfWork / EntityFramework。

这是我的代码

/*Creating the list and adding to UnitOfWork repository*/
....
using (TransactionScope scope = new TransactionScope())
        {
            _unitOfWork.Save();
            ExportGroups(myGroupList);
            scope.Complete();
        }

这是ExportGroups函数的片段

public void ExportGroups(IEnumerable<Group> groups)
{
     /*Generating BrokeredMessage message*/
     Task.Factory.StartNew(() =>
        {
            MessagingFactory factory = CreateMessagingFactory(...);
            if (factory != null)
            {
                var sender = factory.CreateMessageSender(topicName);
                sender.Send(message);
            }
        }).Wait();

}

这在我的开发环境中没有任何问题。但是当我们投入生产时,我得到以下错误

&#34; System.InvalidOperationException:其他资源管理器/ DTC不支持本地事务。&#34;

在机器上启用了DTC,我们使用它来处理其他交易就好了,但它们都没有使用ServiceBus。

[编辑=添加堆栈跟踪]

Server stack trace: 
   at Microsoft.ServiceBus.Messaging.Sbmp.SbmpResourceManager.EnlistAsyncResult..ctor(SbmpResourceManager resourceManager, Transaction transaction, IRequestSessionChannel channel, SbmpMessageCreator messageCreator, Action`1 partitionInfoSetter, TimeSpan timeout, AsyncCallback callback, Object state)
   at Microsoft.ServiceBus.Messaging.Sbmp.SbmpResourceManager.BeginEnlist(Transaction transaction, IRequestSessionChannel channel, SbmpMessageCreator messageCreator, Action`1 partitionInfoSetter, TimeSpan timeout, AsyncCallback callback, Object state)
   at Microsoft.ServiceBus.Messaging.Sbmp.SbmpTransactionalAsyncResult`1.<>c__DisplayClass3e.<GetAsyncSteps>b__38(TIteratorAsyncResult thisPtr, TimeSpan t, AsyncCallback c, Object s)
   at Microsoft.ServiceBus.Messaging.IteratorAsyncResult`1.EnumerateSteps(CurrentThreadType state)
   at Microsoft.ServiceBus.Messaging.IteratorAsyncResult`1.Start()

Exception rethrown at [0]: 
   at Microsoft.ServiceBus.Common.AsyncResult.End[TAsyncResult](IAsyncResult result)
   at Microsoft.ServiceBus.Messaging.Sbmp.SbmpMessageSender.EndSendCommand(IAsyncResult result)
   at Microsoft.ServiceBus.Messaging.Sbmp.SbmpMessageSender.OnEndSend(IAsyncResult result)
   at Microsoft.ServiceBus.Messaging.IteratorAsyncResult`1.EnumerateSteps(CurrentThreadType state)

Exception rethrown at [1]: 
   at Microsoft.ServiceBus.Common.AsyncResult.End[TAsyncResult](IAsyncResult result)
   at Microsoft.ServiceBus.Messaging.IteratorAsyncResult`1.RunSynchronously()
   at Microsoft.ServiceBus.Messaging.MessageSender.Send(TrackingContext trackingContext, IEnumerable`1 messages, TimeSpan timeout)
   at System.Threading.Tasks.Task.Execute()
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at System.Threading.Tasks.Task.Wait()
   at ....GroupService.ExportGroups(IEnumerable<Group> groups)

2 个答案:

答案 0 :(得分:2)

不同的Windows Azure服务不支持事务。也就是说有很多ways to send messages to service bus with transactional guarantees

HTH! SREE

答案 1 :(得分:0)

using (TransactionScope scope = new TransactionScope()
{
    //Database call

    using (var transaction = new TransactionScope(TransactionScopeOption.RequiresNew, TransactionScopeAsyncFlowOption.Enabled))
    {
        sender.Send(message);
        transaction.Complete();
    }
}