English 中文(简体)
The service operation requires a transaction to be flowed
原标题:
  • 时间:2009-11-09 17:56:52
  •  标签:
  • wcf

I am facing strange issue with our WCF service. The same code was working fine until recently we added more OperationContracts(Web Methods).

We have common 3 tier architecture.

  • DAL (WCF)
  • BLL
  • Web UI

Here is my quick sample code:

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();
   }
}

Usage in Web UI:

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

I get "The service operation requires a transaction to be flowed." in my BLL when trying to call AddPerson method in service. Not much luck after enabling tracing in web.config.

Detailed Stack Trace:

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)

Client Configuration:

<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>
最佳回答

I finally figured it out! I manually generated Service Reference proxy class and config file using svcutil tool and used in BLL. Worked fine!

VS version: 2008

WCF service was referenced as "Service Reference" in the BLL. After updating WCF "Service Reference", OperationContracts of recently added ServiceContract in Reference.cs(proxy class) were missing TransactionFlow attribute. This is mainly started happening after adding new ServiceContracts to the service. One interesting thing noticed was, app.config had <CustomBinding> for newly added ServiceContract in lieu of <wsHttpBinding>. Appears to be issue the way with VS 2008 generates Service Reference.

问题回答

The problem is not in your service, but in your client code. The service operation as you ve defined it requires that you call it with a transaction already started on the client side. Is the call on the client side inside a TransactionScope?

Have you tried adding

[OperationBehavior(TransactionScopeRequired=true)] 

on the implementation of the contract ?

Edit: Just for kicks, have you tried regenerating the client proxy?

You must add transactionFlow option on your client configuration manually, As adding service proxy by adding service reference will not include transactionFlow attribute.
That is by design.So even when you add trasactionFlow=true in service it will be false in client configuration when you add it by adding service reference.

what you needed to do you just find transactionFlow attribute and set it to true.

Three required steps for transaction to flow
1. Mark service contract with Attribute [Transaction(TransactionFlowOption.Allowed)]
2. Add transactino support to code i.e. Operation so set property of OperationBehaviour attribute to [OperationBehaviour(TransactionScopeRequired=true)].
3. Add bindingConfiguration with TransactionFlow=true on both servie and client.





相关问题
WCF DataMember Serializing questions

Ok, so I was part way through the long winded process of creating DTOs for sending my model over the wire and I don t feel like I m going down the right route. My issue is that most of the entities ...

Access WCF service on same server

I have a .NET website with a WCF service. How do I access the current operations context of my service? One possible work around is to just make a call to the service within the app...but that seems ...

WCF binding error

So I got into work early today and got the latest from source control. When I try to launch our ASP.NET application, I get this exception: "The binding at system.serviceModel/bindings/wsHttpBinding ...

The service operation requires a transaction to be flowed

I am facing strange issue with our WCF service. The same code was working fine until recently we added more OperationContracts(Web Methods). We have common 3 tier architecture. DAL (WCF) BLL Web ...

热门标签