【问题标题】:The service operation requires a transaction to be flowed服务操作需要处理一个事务
【发布时间】:2009-11-09 17:56:52
【问题描述】:

我的 WCF 服务遇到了奇怪的问题。相同的代码运行良好,直到最近我们添加了更多的 OperationContracts(Web 方法)。

我们有通用的 3 层架构。

  • DAL (WCF)
  • BLL
  • 网页界面

这是我的快速示例代码:

DAL (WCF):

[ServiceContract]
interface IPerson
{
   [OperationContract]
   [TransactionFlow(TransactionFlowOption.Mandatory)]
   int AddPerson(Person p);
}


// AddPerson is implemented in the service
[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
public int AddPerson(Person p)
{
  // LINQ DataContext stuff goes here
}

BLL:

public class EmployeeBLL 
{
   public void AddNewEmployee(Person p)
   {
       using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required))
            {
                try
                {
                   PersonClient perClient = new PersonClient();
                   int personId = perClient.AddPerson(p);
                   ts.Complete();
                }
                catch (Exception ex)
                {
                   // Log exception
                }
                finally
                {
                    ts.Dispose();
                }
            }
            perClient.Close();
   }
}

在网页界面中的使用:

EmployeeBLL empBLL = new EmployeeBLL ()
empBLL.AddNewEmployee(person);

我收到“服务操作需要处理事务。”在我的 BLL 中尝试在服务中调用 AddPerson 方法时。在 web.config 中启用跟踪后运气不佳。

详细的堆栈跟踪:

Server stack trace: 
   at System.ServiceModel.Channels.ServiceChannel.ThrowIfFaultUnderstood(Message reply, MessageFault fault, String action, MessageVersion version, FaultConverter faultConverter)
   at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs)
   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]: 
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)

客户端配置:

<system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="WSHttpBinding_IEmployee" closeTimeout="00:01:00"
              openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
              bypassProxyOnLocal="false" transactionFlow="true" hostNameComparisonMode="StrongWildcard"
              maxBufferPoolSize="524288" maxReceivedMessageSize="5000000"
              messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
              allowCookies="false">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
              maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <reliableSession ordered="true" inactivityTimeout="00:10:00"
              enabled="false" />
          <security mode="Message">
            <transport clientCredentialType="Windows" proxyCredentialType="None"
                realm="" />
            <message clientCredentialType="Windows" negotiateServiceCredential="true"
            algorithmSuite="Default" establishSecurityContext="true" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://localhost:2882/Test.svc"
          binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IEmployee"
          contract="Test.IEmployee" name="WSHttpBinding_IEmployee">
        <identity>
          <dns value="localhost" />
        </identity>
      </endpoint>
    </client>
</system.serviceModel>

【问题讨论】:

  • 您使用的是什么绑定? NetTcpBinding、NetNamedPipeBinding、WSHttpBinding、WSDualHttpBinding 和 WSFederationHttpBinding 支持事务。
  • 只是出于好奇,当您设置reliableSession enabled=true而不是false时,这是否会失败。我意识到事务不需要可靠的消息传递,我只想确认它仍然会引发异常。
  • 我没试过,但可以试一试。基于以下我也不认为交易需要可靠的会话。 msdn.microsoft.com/en-us/library/ms733136.aspx

标签: wcf


【解决方案1】:

我终于明白了!我使用 svcutil 工具手动生成了服务引用代理类和配置文件,并在 BLL 中使用。效果很好!

VS 版本:2008

WCF 服务在 BLL 中被称为“服务引用”。更新 WCF“服务参考”后,Reference.cs(代理类)中最近添加的 ServiceContract 的 OperationContracts 缺少 TransactionFlow 属性。这主要是在向服务添加新的 ServiceContract 之后开始发生的。注意到的一件有趣的事情是,app.config 有 &lt;CustomBinding&gt; 用于新添加的 ServiceContract 代替 &lt;wsHttpBinding&gt;. 似乎是 VS 2008 生成服务参考的方式。

【讨论】:

    【解决方案2】:

    问题不在于您的服务,而在于您的客户端代码。您定义的服务操作要求您使用已经在客户端启动的事务来调用它。客户端的调用是否在 TransactionScope 内?

    【讨论】:

    • 是的。客户端调用在 TransactionScope 内。请原谅我格式化。我应该在 中包装代码。请参考已编辑的问题。
    • 啊,是的,好多了,我现在明白了。嗯...很有趣,不知道为什么它也不会流动。你也可以包括你的客户端配置吗?日志配置不太重要。
    • 我刚刚添加了我的客户端配置。相同的代码运行良好,直到最近我们添加了更多 OperationContracts(Web 方法)。很少有人建议将服务拆分为多个服务,但不完全确定为什么需要这样做。谢谢你的时间。欣赏它。
    • 是的,添加更多操作确实不应该影响其他操作,除非同时更改其他服务级别设置。嗯...客户端配置对我来说看起来不错。我不确定这里发生了什么。我个人现在正在深入研究 App_tracelog.svclog,寻找 WCF 拒绝请求的原因。
    • 我开始深入研究 app_tracelog.svclog。 - 通过通道发送消息(成功) - 通过通道接收消息(成功)... 身份验证成功。安全协议验证传入的消息 A message was read (Action: schemas.microsoft.com/net/2005/12/…) 然后抛出异常 (System.ServiceModel.ProtocolException, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)。
    【解决方案3】:

    你有没有尝试添加

    [OperationBehavior(TransactionScopeRequired=true)] 
    

    关于合同的实施

    编辑: 只是为了好玩,您是否尝试过重新生成客户端代理?

    【讨论】:

    • 是的。 [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
    【解决方案4】:

    您必须在客户端配置中手动添加 transactionFlow 选项,因为通过添加服务引用添加服务代理将不包含 transactionFlow 属性。
    这是设计使然。因此,即使您在服务中添加 trasactionFlow=true,当您通过添加服务引用来添加它时,客户端配置中也会为 false。

    您只需找到 transactionFlow 属性并将其设置为 true 即可。

    交易流程的三个必需步骤
    1. 使用属性[Transaction(TransactionFlowOption.Allowed)]标记服务合同
    2. 为代码添加对事务的支持,即操作,因此将 OperationBehaviour 属性的属性设置为 [OperationBehaviour(TransactionScopeRequired=true)]
    3. 在服务端和客户端上添加 TransactionFlow=true 的 bindingConfiguration。

    【讨论】:

      猜你喜欢
      • 2021-09-24
      • 1970-01-01
      • 1970-01-01
      • 2018-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-19
      相关资源
      最近更新 更多