Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 检测不可用的池连接_C#_Sql Server_Ado.net_Connection Pooling_Application Role - Fatal编程技术网

C# 检测不可用的池连接

C# 检测不可用的池连接,c#,sql-server,ado.net,connection-pooling,application-role,C#,Sql Server,Ado.net,Connection Pooling,Application Role,当我试图用设置SqlConnection上的应用程序角色时,有时会在Windows事件日志中出现以下错误 连接已断开,因为打开连接的主体随后假定了新的安全上下文,然后尝试在其模拟的安全上下文下重置连接。不支持此方案。请参阅联机丛书中的“模拟概述”。) 。。。并且在我的应用程序中抛出一个匹配的异常 这些是池连接,曾经有一段时间连接池与应用程序角色不兼容-事实上,Microsoft的旧建议是(!!),但随着它的引入,现在(理论上)可以在将连接返回池之前清除连接 我相信这些错误发生在(由于未知原因)s

当我试图用设置SqlConnection上的应用程序角色时,有时会在Windows事件日志中出现以下错误

连接已断开,因为打开连接的主体随后假定了新的安全上下文,然后尝试在其模拟的安全上下文下重置连接。不支持此方案。请参阅联机丛书中的“模拟概述”。)

。。。并且在我的应用程序中抛出一个匹配的异常

这些是池连接,曾经有一段时间连接池与应用程序角色不兼容-事实上,Microsoft的旧建议是(!!),但随着它的引入,现在(理论上)可以在将连接返回池之前清除连接

我相信这些错误发生在(由于未知原因)sp_unsetapprole在连接关闭并返回到连接池之前未在连接上运行时。从池返回此连接时,sp_approle将注定失败

我可以捕获并处理此异常,但我更愿意检测即将发生的故障,并完全避免异常(以及事件日志中的消息)

是否可以在不引起异常的情况下检测问题


欢迎您的想法或建议

这是合乎逻辑的,使用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();
            }
        }
    }
}
  • 您将创建对应于调用sp_setapprole存储过程的SqlCommand。您可以生成cookie并将其存储在私有成员变量中
  • 这是您创建连接的地方
  • 客户端代码如下所示:

    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();
                }
            }
        }
    }
    
  • 您将创建对应于调用sp_setapprole存储过程的SqlCommand。您可以生成cookie并将其存储在私有成员变量中
  • 这是您创建连接的地方
  • 客户端代码如下所示:

    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,这个问题是关于是否可能检测到未调用它的场景。