System.Web.Services.WebService - 是否可以隔离每个客户端的服务 [英] System.Web.Services.WebService - Is it possible to isolate the service per client
问题描述
我有一个遗产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 varsExternalLib.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屋!