gpt4 book ai didi

c# - "connection has been disabled"快速创建/删除数据库时的错误信息

转载 作者:太空宇宙 更新时间:2023-11-03 14:08:30 26 4
gpt4 key购买 nike

简介

我正在编写一个 Web 应用程序(C#/ASP.NET MVC 3、.NET Framework 4、MS SQL Server 2008、用于数据库连接的 System.Data.ODBC)并且我在创建数据库方面遇到了很多问题/删除。

我要求应用程序应该能够创建和删除数据库。

问题

应用程序未能通过该功能的压力测试。更具体地说,如果客户端开始快速创建、删除、再次创建具有相同名称的数据库,那么最终(~第 5 次请求)服务器代码抛出 ODBCException 'Connection has been disabled.'。在所有已执行测试的机器上都会观察到此行为 - 确切的失败请求可能不是第 5 个,而是在该值附近的某个位置。

研究

用谷歌搜索异常给出了非常低的输出——异常看起来很普通,没有发现类似的问题。我发现的一个建议是,我的开发 Windows 7 可能无法处理大量同时连接,因为它不是服务器操作系统。我已尝试在 Windows 2008 Server 上安装我们的应用程序 - 行为几乎没有变化,只是在发生异常之前处理了更多请求。

代码和实现的附加注释

数据库是使用这样的存储过程创建的:

CREATE PROCEDURE [dbo].[sp_DBCreate]
...
@databasename nvarchar(124) -- 124 is max length of database file names
AS
DECLARE @sql nvarchar(150);
BEGIN
...
-- Create a new database
SET @sql = N'CREATE DATABASE ' + quotename(@databasename, '[');
EXEC(@sql);

IF @@ERROR <> 0
RETURN -2;
...
RETURN 0;
END

使用以下 SP 删除数据库:

CREATE PROCEDURE [dbo].[sp_DomainDelete]
...
@databasename nvarchar(124) -- 124 is max length of database file names
AS
DECLARE @sql nvarchar(200);
BEGIN
...
-- check if database exists
IF EXISTS(SELECT * FROM [sys].[databases] WHERE [name] = @databasename)
BEGIN
-- drop all active connections
SET @sql = N'ALTER DATABASE' + quotename(@databasename, '[') + ' SET SINGLE_USER WITH ROLLBACK IMMEDIATE';
EXEC(@sql);
-- Delete database
SET @sql = N'DROP DATABASE ' + quotename(@databasename, '[');
EXEC(@sql);

IF @@ERROR <> 0
RETURN -1; --error deleting database
END
--ELSE database does not exist. consider it deleted.

RETURN 0;
END

在这两个 SP 中,我都跳过了不太相关的部分,例如健全性检查。

我没有使用任何 ORM,所有 SP 都是通过使用 OdbcCommand 实例从代码中调用的。为每个函数调用创建新的 OdbcConnection

我真诚地希望有人能给我解决问题的线索。

UPD:如果我们只是快速创建一堆数据库,就会出现完全相同的问题。感谢大家对数据库删除代码的建议,但我更愿意为更普遍的问题提供解决方案或至少提示 - 即使根本不删除数据库也会发生的问题。

UPD2:以下代码用于SP调用:

public static int ExecuteNonQuery(string sql, params object[] parameters)
{
try
{
var command = new OdbcCommand();
Prepare(command, new OdbcConnection( GetConnectionString() /*irrelevant*/), null, CommandType.Text, sql,
parameters == null ?
new List<OdbcParameter>().ToArray() :
parameters.Select(p => p is OdbcParameter ? (OdbcParameter)p : new OdbcParameter(string.Empty, p)).ToArray());

return command.ExecuteNonQuery();
}
catch (OdbcException ex)
{
// Logging here
throw;
}
}

public static void Prepare(
OdbcCommand command,
OdbcConnection connection,
OdbcTransaction transaction,
CommandType commandType,
string commandText,
params OdbcParameter[] commandParameters)
{
if (connection.State != ConnectionState.Open)
{
connection.Open();
}
command.Connection = connection;
command.CommandText = commandText;
if (transaction != null)
{
command.Transaction = transaction;
}
command.CommandType = commandType;
if (commandParameters != null)
{
command.Parameters.AddRange(
commandParameters.Select(p => p.Value==null &&
p.Direction == ParameterDirection.Input ?
new OdbcParameter(p.ParameterName, DBNull.Value) : p).ToArray());
}
}

示例连接字符串:

Driver={SQL Server}; Server=LOCALHOST;Uid=sa;Pwd=<password here>;

最佳答案

好的。 OdbcConnection 可能存在范围问题,但在完成连接后您似乎也没有关闭连接。这可能意味着您依赖池管理器关闭未使用的连接并在它们超时时将它们返回到池中。 using block 将在完成时自动关闭并处理连接,允许它返回到连接池。

试试这段代码:

public static int ExecuteNonQuery(string sql, params object[] parameters)
{
int result = 0;
try
{
var command = new OdbcCommand();
using (OdbcConnection connection = new OdbcConnection(GetConnectionString() /*irrelevant*/))
{
connection.Open();
Prepare(command, connection, null, CommandType.Text, sql,
parameters == null ?
new List<OdbcParameter>().ToArray() :
parameters.Select(p => p is OdbcParameter ? (OdbcParameter)p : new OdbcParameter(string.Empty, p)).ToArray());

result = command.ExecuteNonQuery();
}

}
catch (OdbcException ex)
{
// Logging here
throw;
}
return result;
}

关于c# - "connection has been disabled"快速创建/删除数据库时的错误信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8589390/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com