C# 检测不可用的池连接
当我试图用设置SqlConnection上的应用程序角色时,有时会在Windows事件日志中出现以下错误 连接已断开,因为打开连接的主体随后假定了新的安全上下文,然后尝试在其模拟的安全上下文下重置连接。不支持此方案。请参阅联机丛书中的“模拟概述”。) 。。。并且在我的应用程序中抛出一个匹配的异常 这些是池连接,曾经有一段时间连接池与应用程序角色不兼容-事实上,Microsoft的旧建议是(!!),但随着它的引入,现在(理论上)可以在将连接返回池之前清除连接 我相信这些错误发生在(由于未知原因)sp_unsetapprole在连接关闭并返回到连接池之前未在连接上运行时。从池返回此连接时,sp_approle将注定失败 我可以捕获并处理此异常,但我更愿意检测即将发生的故障,并完全避免异常(以及事件日志中的消息) 是否可以在不引起异常的情况下检测问题C# 检测不可用的池连接,c#,sql-server,ado.net,connection-pooling,application-role,C#,Sql Server,Ado.net,Connection Pooling,Application Role,当我试图用设置SqlConnection上的应用程序角色时,有时会在Windows事件日志中出现以下错误 连接已断开,因为打开连接的主体随后假定了新的安全上下文,然后尝试在其模拟的安全上下文下重置连接。不支持此方案。请参阅联机丛书中的“模拟概述”。) 。。。并且在我的应用程序中抛出一个匹配的异常 这些是池连接,曾经有一段时间连接池与应用程序角色不兼容-事实上,Microsoft的旧建议是(!!),但随着它的引入,现在(理论上)可以在将连接返回池之前清除连接 我相信这些错误发生在(由于未知原因)s
欢迎您的想法或建议 这是合乎逻辑的,使用sp_setapprole的经验也不多,但在调用之前是否可能检查安全上下文?或者先检查安全权限和上下文?这是一种逻辑,在使用sp_setapprole方面没有太多经验,但在进行调用之前是否可能检查安全上下文?或者先检查安全权限和上下文?似乎您正在调用sp_setapprole,但没有调用sp_unsetapprole,然后让连接返回池 我建议在IDisposable的实现中使用一个结构(或者一个类,如果您必须跨方法使用它),它将为您解决这个问题:
public struct ConnectionManager : IDisposable
{
// The backing for the connection.
private SqlConnection connection;
// The connection.
public SqlConnection Connection { get { return connection; } }
public void Dispose()
{
// If there is no connection, get out.
if (connection == null)
{
// Get out.
return;
}
// Make sure connection is cleaned up.
using (SqlConnection c = connection)
{
// See (1). Create the command for sp_unsetapprole
// and then execute.
using (SqlCommand command = ...)
{
// Execute the command.
command.ExecuteNonQuery();
}
}
}
public ConnectionManager Release()
{
// Create a copy to return.
ConnectionManager retVal = this;
// Set the connection to null.
retVal.connection = null;
// Return the copy.
return retVal;
}
public static ConnectionManager Create()
{
// Create the return value, use a using statement.
using (ConnectionManager cm = new ConnectionManager())
{
// Create the connection and assign here.
// See (2).
cm.connection = ...
// Create the command to call sp_setapprole here.
using (SqlCommand command = ...)
{
// Execute the command.
command.ExecuteNonQuery();
// Return the connection, but call release
// so the connection is still live on return.
return cm.Release();
}
}
}
}
using (ConnectionManager cm = ConnectionManager.Create())
{
// Get the SqlConnection for use.
// No need for a using statement, when Dispose is
// called on the connection manager, the connection will be
// closed.
SqlConnection connection = cm.Connection;
// Use connection appropriately.
}
似乎您正在调用sp_setapprole,但没有调用sp_unsetapprole,然后让连接返回到池中 我建议在IDisposable的实现中使用一个结构(或者一个类,如果您必须跨方法使用它),它将为您解决这个问题:
public struct ConnectionManager : IDisposable
{
// The backing for the connection.
private SqlConnection connection;
// The connection.
public SqlConnection Connection { get { return connection; } }
public void Dispose()
{
// If there is no connection, get out.
if (connection == null)
{
// Get out.
return;
}
// Make sure connection is cleaned up.
using (SqlConnection c = connection)
{
// See (1). Create the command for sp_unsetapprole
// and then execute.
using (SqlCommand command = ...)
{
// Execute the command.
command.ExecuteNonQuery();
}
}
}
public ConnectionManager Release()
{
// Create a copy to return.
ConnectionManager retVal = this;
// Set the connection to null.
retVal.connection = null;
// Return the copy.
return retVal;
}
public static ConnectionManager Create()
{
// Create the return value, use a using statement.
using (ConnectionManager cm = new ConnectionManager())
{
// Create the connection and assign here.
// See (2).
cm.connection = ...
// Create the command to call sp_setapprole here.
using (SqlCommand command = ...)
{
// Execute the command.
command.ExecuteNonQuery();
// Return the connection, but call release
// so the connection is still live on return.
return cm.Release();
}
}
}
}
using (ConnectionManager cm = ConnectionManager.Create())
{
// Get the SqlConnection for use.
// No need for a using statement, when Dispose is
// called on the connection manager, the connection will be
// closed.
SqlConnection connection = cm.Connection;
// Use connection appropriately.
}
不,不可能。不,不可能。这有点脏,但如果原始用户有权查看服务器状态,
select*from sys.sysprocesses
将在角色未处于活动状态时返回所有进程,在当前进程处于活动状态时返回一行。这有点脏,但如果原始用户有权查看服务器状态,select*from sys.sysprocesses
将在角色未处于活动状态时返回所有进程,在当前进程处于活动状态时返回一行。据我所知,在现在不可用的连接上执行任何sql都不可能不引发异常。所以我不能通过询问连接来检查安全上下文。这很公平。那就别提这个主意了。但是,您不能对另一个连接进行检查,或者这会影响整个应用程序吗?这是一个连接池问题,因此尽管我可以获得另一个连接,但我无法用它询问第一个连接的状态。我所拥有的只是一个可能可用或不可用的连接,在我尝试使用它之前我不知道。据我所知,在现在不可用的连接上执行任何sql都不可能不引发异常。所以我不能通过询问连接来检查安全上下文。这很公平。那就别提这个主意了。但是,您不能对另一个连接进行检查,或者这会影响整个应用程序吗?这是一个连接池问题,因此尽管我可以获得另一个连接,但我无法用它询问第一个连接的状态。我所拥有的只是一个可能可用或不可用的连接,直到我尝试使用它时我才知道。我确实调用unsetapprole,这个问题是关于是否可能检测到未调用它的场景。我确实调用unsetapprole,这个问题是关于是否可能检测到未调用它的场景。