"交易已中止"创建新TransactionScope时的异常()

时间:2014-08-26 17:21:34

标签: c# wcf transactionscope

这是我的第一个WCF客户端和服务器端。 SQL server 2008。

我被迫在我的Windows窗体应用程序中使用TransactionScope事务,该应用程序作为客户端针对WCF服务运行。我之前没有使用过这种类型的交易,通常使用我喜欢的connection.BeginTransaction(),因为它更容易理解正在发生的事情。

我调用了一个函数(我希望嵌套事务),但是我创建一个新的TransactionScope实例的一个调用是在#34;事务已中止"例外。 内部异常为空。 我假设交易在此之前已经回滚,但我不知道如何跟踪是否有正在进行的环境事务以及状态是什么。

示例客户端(不是真正的代码。我检查过所有的func都在使用scope.Commit()) 有关如何追踪问题的任何帮助吗?

(我经常会收到有关必须启动MSDTC服务的错误消息,但我不知道为什么在使用单一数据库/ wcf服务时使用分布式服务器<) / p>

void Function1(AMessageObj m)
{
  using (var client = GetOpenWebClient())
    WriteMessage(m, client);
}

void WriteMessage(AMessage m, OpenWebClient client)
{
  using (var scope = new TransactionScope())
  {
    var audit = GetSomeAuditInfo(AMessage.UserId, client);
    WriteTheMessage(AMessage, client);
    WriteAudit(audit, client);
    client.SetTime(DateTime.Now);
    scope.Commit();
  }  
}

AuditRecord GetSomeAuditInfo(Int userId, OpenWebClient client)
{
  var result = client.ReadAuditRecord(userId);
  return AuditRecord.FromWeb(result);
}

void WriteTheMessage(AMessage msg, OpenWebClient client)
{
  using (var scope = new TransactionScope())
  {
    client.WriteTheMessage(msg.ToWeb());
    scope.Commit();
  }
}

void WriteAudit(AuditRecord audit, OpenWebClient client)
{
  using (var scope = new TransactionScope())
  {
    client.WriteAudit(audit.ToWeb());
    scope.Commit();
  }
}

示例服务WCF

[ServiceContract]
interface IService
{
  [OperationContract]
  void WriteTheMessage(WebRecord message);

  [OperationContract]
  WebRecord ReadAuditRecord(int userId);

  [OperationContract]
  void WriteAudit(WebRecord audit);
}

class MyWebService : IService
{
  [OperationBehavior(TransactionScopeRequired = true)]
  void IService.WriteTheMessage(WebRecord record)
  {
    using (var connection = GetOpenConnection())
    {
      dowritethings;
    }
  }

  [OperationBehavior(TransactionScopeRequired = false)]
  WebRecord IService.ReadAuditRecord(WebRecord record)
  {
    using (var connection = GetOpenConnection())
    {
      return readthings;
    }
  }

  [OperationBehavior(TransactionScopeRequired = true)]
  void IService.WriteAudit(WebRecord record)
  {
    using (var connection = GetOpenConnection())
    {
      dowritethings;
    }
  }
}

2 个答案:

答案 0 :(得分:2)

我在如何查看环境事务状态时进行了网络搜索,并提出了我放入监视窗口的Transaction.Current属性。 这显示在一次外部函数调用后我完全错过了Aborted。走进那里我发现我叫回归;从创建事务和提交事务之间的功能,因此中止。

感谢您的帮助

答案 1 :(得分:1)

您在服务器上打开的每个连接都是分布式实体。偶然,您经常在测试期间从连接池获得相同的物理连接。这是一种令人讨厌的行为,因为它会导致您在测试期间找不到问题。对于数据库,此设置以非确定性方式运行。

在任何情况下,您都应该在此处分发事务,因为WCF和SQL Server是不同的资源。这应该确定性地升级为使用MSDTC。

  

我假设事务已在此之前回滚

最有可能。使用WCF事务,您的代码始终设置了环境事务。可能在某个地方有一些你没注意到的异常。设置调试器以中断所有异常。使用Fiddler观察通过线路发送的响应。也许它们包含某种错误。 WCF跟踪是另一种选择。

如果这没有导致任何尝试创建可靠的repro。通常你会在过程中自己发现错误。