System.Web.Services.WebService - 是否可以隔离每个客户端的服务 [英] System.Web.Services.WebService - Is it possible to isolate the service per client

查看:288
本文介绍了System.Web.Services.WebService - 是否可以隔离每个客户端的服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个遗产System.Web.Services.WebService(不是WCF),我必须维护。

I have an legacy System.Web.Services.WebService (not WCF) that I have to maintain.

偶尔我遇到一些我会描述的有线行为作为竞争条件。

Ocassionly I run into some wired behaviours that I would describe as race conditions.


  • 服务挂起并且必须重新启动。

  • Either the service hangs and has to be restarted.

有时我得到这个例外:

System.NotSupportedException: Multiple simultaneous connections
or connections with different connection strings inside the same 
transaction are not currently supported.
    at MySql.Data.MySqlClient.MySqlConnection.Open()
    ...


我知道根本原因是什么。该服务使用一个与mysql对话的lib,并没有考虑到webservices的设计。不幸的是我无法更改此库。

I know whats the root cause. The service utilizes a lib that talks to mysql and was not designed with webservices in mind. Unfortunatly I cannot change this lib.

一个示例webmethod如下所示:

One example webmethod looks like this:

[WebMethod(EnableSession = true)]
public void DoSomething()
{
    var login = this.Session["login"] as LoginDetails;
    ExternalLib.SetLoginData(login.Schema, login.User, login.Pass);

    ExternalLib.PerformTask();

}

所以这里的问题是:


  • ExternalLib.SetLoginData 只设置一些全局变量

  • ExternalLib.PerformTask 执行数据库调用,有些是在事务中。

  • 过程类似于 1。创建MySqlConnection或从缓存中获取2.创建MySqlCommand 3.执行命令4. Dispose命令

  • ExternalLib.SetLoginData just set's some global vars
  • ExternalLib.PerformTask performs database calls, some inside a transaction.
  • The process is like 1. Create MySqlConnection or take it from cache 2. Create MySqlCommand 3. Execute Command 4. Dispose command

客户端a)调用 DoSomething()并初始化他的连接。完成他的工作的一半客户端b)调用 DoSomething()这显然改变了客户端a的登录数据,并且事务中的下一个调用将使用来自客户端b的登录)导致交易。

Client a) calls DoSomething() and I init his connection. Half way done with his job Client b) calls DoSomething() which apparently changes the Login-Data for client a and the next call inside the transaction will use the login from client b) which causes the transaction.

无论如何,我知道这是一个糟糕的设计,但我的问题是如何解决这个问题。
目前(因为我只有10个客户端)我在不同的端口上创建了一个专用网站,它们都指向相同的根目录,但这是一个不方便的解决方案。

Anyway, I know this is a bad design but my question is how to workaround this. Currently (since I only have 10 clients) I created a dedicated Website on a differnet port which all point to the same root directory but this is an akward solution.

也许有可能在其领域内运行每个会话。有什么建议么。如果我正确理解此页面的WCF是默认行为: http:// msdn .microsoft.com / zh-CN / magazine / cc163590.aspx

Maybe there is a possibility to run every session inside its on realm. Any suggestions. If I understand this page correctly for WCF is is the default behaviour: http://msdn.microsoft.com/en-us/magazine/cc163590.aspx


每次呼叫服务

每次呼叫服务是Windows Communication
基础默认实例化模式。当为每次调用激活配置的服务类型为
时,服务实例(公共
语言运行时(CLR)对象)仅在客户端调用处于
进度时存在。每个客户端请求都会获得一个新的专用服务实例。

Per-Call Services
Per-call services are the Windows Communication Foundation default instantiation mode. When the service type is configured for per-call activation, a service instance, a common language runtime (CLR) object, exists only while a client call is in progress. Every client request gets a new dedicated service instance.


推荐答案

看来这可能是一个线程问题是你可以锁定 ExternalLib 以防止单独的实例调用代码。

Seeing as this is probably a threading issue you can lock the ExternalLib to prevent separate instances from calling the code.

public class ExtenalLibWrapper
{
    private static object Locker = new object();

    public void DoSomething(LoginDetails details)
    {
        lock(Locker)
        {
            ExternalLib.SetLoginData(login.Schema, login.User, login.pass);
            ExternalLib.PerformTask();
        }
    }
}

这篇关于System.Web.Services.WebService - 是否可以隔离每个客户端的服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆