多用户连接并同时执行 CRUD
本文关键字:执行 CRUD 连接 多用户 | 更新日期: 2023-09-27 17:55:23
我正在使用 ASP.NET Framework 4,IIS 7和SQL Server 2008 R2。
我收到如下错误: {column} not found in selected DataSource,
SQL Reader is close
, ....
它仅在以下情况下发生:
- 连接了多个用户。
- 它们同时进行 CRUD(创建、重新引用、更新、删除)调用。
奇怪的是,它逃脱了我的捕获:
try{
Connexion_D.GetConnected();
// doing CRUD
}
catch{
// catching Error, avoid yellow page aspx
}
finally
{
Connexion_D.CloseConnection();
}
还有我的连接类:
public class Connexion_D
{
static public SqlConnection conn;
static public SqlConnection GetConnected()
{
try
{
String strConnectionString = ConfigurationManager.ConnectionStrings["xxxxx"].ConnectionString;
conn = new SqlConnection(strConnectionString);
}
catch (Exception excThrown)
{
conn = null;
throw new Exception(excThrown.InnerException.Message, excThrown);
}
// Ouverture et restitution de la connexion en cours
if (conn.State == ConnectionState.Closed) conn.Open();
return conn;
}
static public Boolean IsConnected
{
get { return (conn != null) && (conn.State != ConnectionState.Closed) && (conn.State != ConnectionState.Broken); }
}
static public void CloseConnection()
{
// Libération de la connexion si elle existe
if (IsConnected) conn.Close();
}
}
所以我不认为代码是错误的/有错误。
我认为这可能是IIS和SQL服务器的配置。
有什么想法吗?
提前感谢。
如果我理解你在做什么正确,那么这看起来非常可疑:
static public SqlConnection conn;
static public SqlConnection GetConnected() {
try
{
String strConnectionString = ConfigurationManager.ConnectionStrings["xxxxx"].ConnectionString;
conn = new SqlConnection(strConnectionString);
}
}
static public void CloseConnection() {
// Libération de la connexion si elle existe
if (IsConnected) conn.Close();
}
您正在使用静态连接变量,这意味着当您关闭它时,您将关闭最后一个打开的连接变量。
在多用户方案中,您可能会遇到这种情况:
- 用户 A:创建连接(并返回连接 1)
- 用户 A:执行查询(针对连接 1 运行)
- 用户 B:创建连接(并返回连接 2)
- 用户 A:关闭连接(上次打开的连接是 2,因此已关闭)
- 用户 B:执行查询(针对连接 2 运行,它已被关闭...砰)
顺便说一句,您可能应该重新考虑将您的连接作为公共成员变量:
static public SqlConnection conn;
这通常被认为是不好的做法,如果类之外的任何代码开始弄乱其内部变量,则可能导致将来意外/难以跟踪的错误。
编辑:
最明显的解决方案似乎是阻止连接是静态的。 然后,客户端代码可能如下所示:
try{
// use using block around connection, calls dispose automatically when
// block ends...
using(var connectionWrapper = new Connexion_D()) {
var connectedConnection = connectionWrapper.GetConnected();
// do CRUD
}
}
catch{
// catching Error, avoid yellow page aspx
// Really you should probably be doing something with the exception (logging?)
// particularly since you go to the effort of throwing it from your Connection_D
// class.
}
您的类代码如下所示:
/* Implement IDisposable to cleanup connection */
public class Connexion_D : IDisposable
{
public SqlConnection conn;
public SqlConnection GetConnected()
{
try
{
String strConnectionString = ConfigurationManager.ConnectionStrings["xxxxx"].ConnectionString;
conn = new SqlConnection(strConnectionString);
}
catch (Exception excThrown)
{
conn = null;
throw new Exception(excThrown.InnerException.Message, excThrown);
}
// Ouverture et restitution de la connexion en cours
if (conn.State == ConnectionState.Closed) conn.Open();
return conn;
}
public Boolean IsConnected
{
get { return (conn != null) && (conn.State != ConnectionState.Closed) && (conn.State != ConnectionState.Broken); }
}
public void CloseConnection()
{
// Libération de la connexion si elle existe
if (IsConnected) {
conn.Close();
conn = null;
}
}
// Implement IDisposable.
// Do not make this method virtual.
// A derived class should not be able to override this method.
public void Dispose()
{
// Close connection
}
}
有关实现 IDisposable 的详细信息,请参阅此处。