Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/273.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# 无法连接到SQL Server会话数据库异常-所有池连接都在使用中_C#_Sql Server_Database_Connection String_Connection Pooling - Fatal编程技术网

C# 无法连接到SQL Server会话数据库异常-所有池连接都在使用中

C# 无法连接到SQL Server会话数据库异常-所有池连接都在使用中,c#,sql-server,database,connection-string,connection-pooling,C#,Sql Server,Database,Connection String,Connection Pooling,在生产过程中,我的日志文件中突然出现以下错误: System.Web.HttpException(0x80004005):引发了类型为“System.Web.HttpException”的异常 System.Web.HttpException(0x80004005):无法连接到SQL Server会话数据库 System.InvalidOperationException:超时已过期。从池中获取连接之前经过的超时时间。发生这种情况的原因可能是所有池连接都在使用中,并且已达到最大池大小 我看了很多

在生产过程中,我的日志文件中突然出现以下错误:

System.Web.HttpException(0x80004005):引发了类型为“System.Web.HttpException”的异常

System.Web.HttpException(0x80004005):无法连接到SQL Server会话数据库

System.InvalidOperationException:超时已过期。从池中获取连接之前经过的超时时间。发生这种情况的原因可能是所有池连接都在使用中,并且已达到最大池大小

我看了很多其他的答案,比如

但我没有连接泄漏,我不想只将最大池设置为 200左右,因为我想知道为什么我突然得到这个例外

以下是我的连接字符串:

<!--Nhibernate-->
<add name="name" 
     connectionString="Server= servername;Initial Catalog=DBname;UID=username;Password=password;MultipleActiveResultSets=true" 
     providerName="System.Data.SqlClient" /> 

<!--Entity Framework-->
<add name="name" 
     connectionString= "metadata=res://*/Models.Model1.csdl|res://*/Models.Model1.ssdl|res://*/Models.Model1.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=servername;initial catalog=DBname;user id=userName;password=password;multipleactiveresultsets=True;App=EntityFramework&quot;" 
     providerName="System.Data.EntityClient" /> 
更新

事实证明,我在实体框架中确实有一个连接泄漏, 一个没有使用
的地方,并且连接没有关闭

例如:

private DbContext context = new DbContext();

...

List<dbObject> SeriesEvents = context.dbObject.Where(e => e.RecurrenceId == entity.RecurrenceId).ToList();
private DbContext context=new DbContext();
...
List serieEvents=context.dbObject.Where(e=>e.RecurrenceId==entity.RecurrenceId).ToList();
上下文
变量未关闭


更重要的是,这个查询产生了比100多个DB查询更多的DB查询。

通常这种连接池问题伴随着连接泄漏而来。数据库操作中可能会出现一些异常,连接可能无法正确关闭。 请添加try{}catch{}finally{}块并关闭finally块中的连接

如果使用
使用,则try-catch-finally是隐式的,运行时本身将关闭连接。因此,不需要显式关闭连接。如果使用
using
块,请从代码中删除
connection.Close()

使用
语句实际上是try{}catch{}finally{}的语法糖,在try{}catch{}finally{}语句中,连接被关闭并在finally by runtime中释放

try
{
     connection.Open();
     // DB Operations
}
finally
{
     connection.Close();                
}

错误消息表明会话状态数据库出现问题,但您提供的信息是针对应用程序连接的。由于连接字符串不同,会话状态的池不同

会话状态问题的常见原因是:1)承载会话状态数据库的实例对于工作负载而言尺寸过小,或2)会话状态清理作业导致长期阻塞

早期.NET版本中的清理作业在一个批处理中删除了所有过期的会话,并因在繁忙站点上造成长期阻塞而臭名昭著,特别是在会话状态为“大量使用”时:

CREATE PROCEDURE dbo.DeleteExpiredSessions
AS
    DECLARE @now datetime
    SET @now = GETUTCDATE()

    DELETE [ASPState].dbo.ASPStateTempSessions
    WHERE Expires < @now

    RETURN 0
创建过程dbo.DeleteExpiredSessions
作为
声明@now datetime
SET@now=GETUTCDATE()
删除[ASPState].dbo.ASPStateTempSessions
现在在哪里
返回0
更高版本的.NET使用游标进行删除,以大大提高并发性

CREATE PROCEDURE dbo.DeleteExpiredSessions
AS
    SET NOCOUNT ON
    SET DEADLOCK_PRIORITY LOW 

    DECLARE @now datetime
    SET @now = GETUTCDATE() 

    CREATE TABLE #tblExpiredSessions 
    ( 
        SessionId nvarchar(88) NOT NULL PRIMARY KEY
    )

    INSERT #tblExpiredSessions (SessionId)
        SELECT SessionId
        FROM [ASPState].dbo.ASPStateTempSessions WITH (READUNCOMMITTED)
        WHERE Expires < @now

    IF @@ROWCOUNT <> 0 
    BEGIN 
        DECLARE ExpiredSessionCursor CURSOR LOCAL FORWARD_ONLY READ_ONLY
        FOR SELECT SessionId FROM #tblExpiredSessions 

        DECLARE @SessionId nvarchar(88)

        OPEN ExpiredSessionCursor

        FETCH NEXT FROM ExpiredSessionCursor INTO @SessionId

        WHILE @@FETCH_STATUS = 0 
            BEGIN
                DELETE FROM [ASPState].dbo.ASPStateTempSessions WHERE SessionId = @SessionId AND Expires < @now
                FETCH NEXT FROM ExpiredSessionCursor INTO @SessionId
            END

        CLOSE ExpiredSessionCursor

        DEALLOCATE ExpiredSessionCursor

    END 

    DROP TABLE #tblExpiredSessions

RETURN 0
创建过程dbo.DeleteExpiredSessions
作为
不计较
将死锁设置为低优先级
声明@now datetime
SET@now=GETUTCDATE()
创建表#tblExpiredSessions
( 
SessionId nvarchar(88)主键不为空
)
插入#tblExpiredSessions(SessionId)
选择SessionId
来自[ASPState].dbo.ASPStateTempSessions与(READUNCOMMITTED)
现在在哪里
如果@@ROWCOUNT 0
开始
声明ExpiredSessionCursor游标本地转发只读
对于从#tblExpiredSessions中选择SessionId
声明@SessionId nvarchar(88)
打开过期的sessioncursor
从ExpiredSessionCursor获取下一个到@SessionId
而@@FETCH\u STATUS=0
开始
从[ASPState].dbo.ASPStateTempSessions中删除,其中SessionId=@SessionId并立即过期
从ExpiredSessionCursor获取下一个到@SessionId
结束
关闭过期的sessioncursor
取消分配过期的SessionCursor
结束
DROP TABLE#tblExpiredSessions
返回0

如果这个问题是由于一个规模较小的实例和扩展不可行,考虑使用会话状态分区来扩展的。

,让我们看看代码<代码>没有连接泄漏>代码>我敢打赌,您没有处理。properly@Charlieface你错了,我处理得很好。我将更新一个示例
db.Database.Connection
属性的实现是什么样子的?连接返回正确的连接,对吗?发生错误时,SQL Server中有多少个连接?在该Sql Server上,您在任何给定时间都有超过32000个连接吗?该Sql Server运行在同一个服务器上还是在单独的服务器上?Web服务器/客户端运行的操作系统是什么?nHiberbate上下文是否有可能泄漏连接而不是EF连接?它是否会在创建连接的多个地方抛出此异常,或者在代码中总是在同一个方法上抛出此异常?我检查的形式使用就足够了,不是吗?他们声称他们使用将连接包装在一个
中,编译器生成一个try/catch,在这种情况下保证调用dispose。如果他们的代码正确地实现了using语句,则添加try/catch将不会有帮助。在这种情况下,请删除代码中的connection.close(),因为它是由using语句自动生成的。@Habeeb正确的是,connection.close()是多余的,我将删除它我接受这个答案,因为最终它被证明是一个连接泄漏问题
CREATE PROCEDURE dbo.DeleteExpiredSessions
AS
    SET NOCOUNT ON
    SET DEADLOCK_PRIORITY LOW 

    DECLARE @now datetime
    SET @now = GETUTCDATE() 

    CREATE TABLE #tblExpiredSessions 
    ( 
        SessionId nvarchar(88) NOT NULL PRIMARY KEY
    )

    INSERT #tblExpiredSessions (SessionId)
        SELECT SessionId
        FROM [ASPState].dbo.ASPStateTempSessions WITH (READUNCOMMITTED)
        WHERE Expires < @now

    IF @@ROWCOUNT <> 0 
    BEGIN 
        DECLARE ExpiredSessionCursor CURSOR LOCAL FORWARD_ONLY READ_ONLY
        FOR SELECT SessionId FROM #tblExpiredSessions 

        DECLARE @SessionId nvarchar(88)

        OPEN ExpiredSessionCursor

        FETCH NEXT FROM ExpiredSessionCursor INTO @SessionId

        WHILE @@FETCH_STATUS = 0 
            BEGIN
                DELETE FROM [ASPState].dbo.ASPStateTempSessions WHERE SessionId = @SessionId AND Expires < @now
                FETCH NEXT FROM ExpiredSessionCursor INTO @SessionId
            END

        CLOSE ExpiredSessionCursor

        DEALLOCATE ExpiredSessionCursor

    END 

    DROP TABLE #tblExpiredSessions

RETURN 0