本文介绍了如何实现同步会话和交易流程的WCF?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在试图回答一个,它成为apparant的既不本人或OP可以同时建造这既是会话 TransactionFlow 启用WCF服务 - 唯一的解决办法我可以提供是消除 TransactionFlow ,以获得WCF会话实例化工作。



虽然逻辑会话的持续时间可以想见,活得比交易(铭记 TransactionFlow 可能意味着事务持有宝贵的服务器资源,如数据库锁,消息队列和事务性文件系统),我无法找到一个明确的参考任何一种方式。确认或拒绝为同时实现这两种功能的possiblility



所以我的问题是:我怎样才能既 InstanceContextMode = InstanceContextMode.PerSession TransactionFlow 在WCF并发工作的



什么被审判?



ITransactionService.cs

  [的ServiceContract(SessionMode = SessionMode.Required )
公共接口ITransactionService
{
[OperationContract的(IsInitiating = TRUE,IsTerminating = FALSE)]
[TransactionFlow(TransactionFlowOption.Mandatory)
INT启动(INT用户名);

[OperationContract的(IsInitiating =假,IsTerminating = TRUE)]
[TransactionFlow(TransactionFlowOption.Mandatory)
INT完成(INT用户id);
}



TransactionService.svc.cs



  [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)] 
公共类TransactionService:ITransactionService
{
公众诠释计数= 0;

[OperationBehavior(TransactionScopeRequired =真)]
公众诠释启动(INT用户id)
{
Debug.Assert的(Transaction.Current!= NULL,没有交易!);
计数=计数+ 1;
返回计数;
}

[OperationBehavior(TransactionScopeRequired =真)]
公众诠释完成(INT用户id)
{
Debug.Assert的(Transaction.Current!=空,没有交易!);
Debug.Assert的(计数大于0,无会话!);
返回计数;
}



Client.cs



 使用(VAR TS =新的TransactionScope())
使用(VAR SVC =新TransactionServiceClient())
{
svc.Start(0);
svc.Finish(0);
ts.Complete();
}



服务的web.config



 <服务和GT; 
<服务名称=WcfLibrary1.TransactionService>
<端点地址=绑定=的wsHttpBinding
合同=WcfLibrary1.ITransactionService>
<同一性GT;
< DNS值=本地主机/>
< /身份>
< /端点>
< /服务>
< /服务>
<&绑定GT;
<&的wsHttpBinding GT;
<结合transactionFlow =真/>
< /&的wsHttpBinding GT;
< /绑定>
< protocolMapping>
<清除计划=HTTP/>
<加入计划=HTTP绑定=的wsHttpBindingbindingConfiguration =transactionFlowEnabled/>
< / protocolMapping>



客户端的web.config



 <&绑定GT; 
<&的wsHttpBinding GT;
<绑定名称=WSHttpBinding_ITransactionServicetransactionFlow =真/>
< /&的wsHttpBinding GT;
< /绑定>
<客户端>
<端点地址=HTTP://本地主机:65171 / TransactionService.svc
结合=的wsHttpBindingbindingConfiguration =WSHttpBinding_ITransactionService
合同=TransactionService.ITransactionServiceNAME = WSHttpBinding_ITransactionService>
<同一性GT;
< DNS值=本地主机/>
< /身份>
< /端点>
< /客户>


解决方案

一些试验和错误之后,现在看来,这是可能的。这个问题似乎是, TransactionFlow 的:




  • 在类的 - ReleaseServiceInstanceOnTransactionComplete =真正

  • 在方法的 - TransactionAutoComplete = TRUE



其中在结合彼此使用时,将导致服务的实例被释放,因而会破坏所有国家保留在现有的会话。



禁用这些选项将保持服务实例活着的会话的持续时间,因此允许 TransactionFlow 会议同时使用:



即在的ServiceContract

  [的ServiceContract(SessionMode = SessionMode.Required) ] 
公共接口ITransactionService
{
[OperationContract的(IsInitiating = TRUE,IsTerminating = FALSE)]
[TransactionFlow(TransactionFlowOption.Mandatory)
INT启动(INT用户id );

[OperationContract的(IsInitiating =假,IsTerminating = TRUE)]
[TransactionFlow(TransactionFlowOption.Mandatory)
INT完成(INT用户id);
}



要么改变这个服务类:

  [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession,
ReleaseServiceInstanceOnTransactionComplete = FALSE)]
公共类TransactionService:ITransactionService
$ { b $ b

或者,在操作方式:

  [OperationBehavior(TransactionScopeRequired = TRUE,
TransactionAutoComplete = FALSE)]
公众诠释启动(INT用户id)
{


While attempting to answer a question, it became apparant that the neither myself or the OP could simultaneously build a WCF service which was both Session and TransactionFlow enabled - the only solution I could offer was to remove TransactionFlow in order to get the WCF Session instancing working.

Although logically Session durations could conceivably outlive Transactions (bearing in mind that TransactionFlow could mean that transactions are holding precious server resources like Database locks, Messaging Queues and transactional file systems), I can't find a definitive reference either way confirming or rejecting the possiblility to concurrently implementing both features.

So my question is : How can I get both InstanceContextMode=InstanceContextMode.PerSession and TransactionFlow working concurrently in WCF?

What was tried:

ITransactionService.cs

[ServiceContract(SessionMode = SessionMode.Required)]
public interface ITransactionService
{
    [OperationContract(IsInitiating = true, IsTerminating = false)]
    [TransactionFlow(TransactionFlowOption.Mandatory)]
    int Start(int userId);

    [OperationContract(IsInitiating = false, IsTerminating = true)]
    [TransactionFlow(TransactionFlowOption.Mandatory)]
    int Finish(int userId);
}

TransactionService.svc.cs

[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
public class TransactionService : ITransactionService
{
    public int count = 0;

    [OperationBehavior(TransactionScopeRequired = true)]
    public int Start(int userId)
    {
        Debug.Assert(Transaction.Current != null, "No Transaction!");
        count = count + 1;
        return count;
    }

    [OperationBehavior(TransactionScopeRequired = true)]
    public int Finish(int userId)
    {
        Debug.Assert(Transaction.Current != null, "No Transaction!");
        Debug.Assert(count > 0, "No Session!");
        return count;
    }

Client.cs

  using (var ts = new TransactionScope())
  using (var svc = new TransactionServiceClient())
  {
      svc.Start(0);
      svc.Finish(0);
      ts.Complete();
  }

Service web.config

  <services>
      <service name="WcfLibrary1.TransactionService">
          <endpoint address="" binding="wsHttpBinding"
          contract="WcfLibrary1.ITransactionService">
              <identity>
                  <dns value="localhost" />
              </identity>
          </endpoint>
      </service>
  </services>
   <bindings>
       <wsHttpBinding>
           <binding transactionFlow="true"/>
       </wsHttpBinding>
   </bindings>
   <protocolMapping>
       <remove scheme="http" />
       <add scheme="http" binding="wsHttpBinding" bindingConfiguration="transactionFlowEnabled"/>
   </protocolMapping>

Client web.config

<bindings>
    <wsHttpBinding>
        <binding name="WSHttpBinding_ITransactionService" transactionFlow="true" />
    </wsHttpBinding>
</bindings>
<client>
    <endpoint address="http://localhost:65171/TransactionService.svc"
        binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ITransactionService"
        contract="TransactionService.ITransactionService" name="WSHttpBinding_ITransactionService">
        <identity>
            <dns value="localhost" />
        </identity>
    </endpoint>
</client>
解决方案

After some trial and error, it seems it is possible. The issue appears to be that the default behaviour of TransactionFlow applies the following default settings:

Which when used in conjunction with each other, will cause the instance of the service to be released, thus destroying any state retained in an existing Session.

Disabling either of these options will keep the Service instance alive for the duration of the Session, and so allowing TransactionFlow and Session to be used simultaneously:

i.e. on the ServiceContract:

[ServiceContract(SessionMode = SessionMode.Required)]
public interface ITransactionService
{
    [OperationContract(IsInitiating = true, IsTerminating = false)]
    [TransactionFlow(TransactionFlowOption.Mandatory)]
    int Start(int userId);

    [OperationContract(IsInitiating = false, IsTerminating = true)]
    [TransactionFlow(TransactionFlowOption.Mandatory)]
    int Finish(int userId);
}

Either change to this on the Service class:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession,
                 ReleaseServiceInstanceOnTransactionComplete = false)]
public class TransactionService : ITransactionService
{

Or, on the Operation:

    [OperationBehavior(TransactionScopeRequired = true, 
                       TransactionAutoComplete = false)]
    public int Start(int userId)
    {

这篇关于如何实现同步会话和交易流程的WCF?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-18 01:40