加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net – .net SqlCommandTimeOut和连接池

发布时间:2020-12-16 06:24:18 所属栏目:asp.Net 来源:网络整理
导读:假设我们正在执行许多不同的sql命令,并且SqlCommand.CommandTimeout以默认值30秒离开. 让我们假设一些sql命令只是长查询,我们可能会得到超时异常. 纠正我,如果我错了,这个例外只是因为.Net不想再等了,但如果我们使用连接池,这个连接可能会保持打开状态,那么s
假设我们正在执行许多不同的sql命令,并且SqlCommand.CommandTimeout以默认值30秒离开.

让我们假设一些sql命令只是长查询,我们可能会得到超时异常.

纠正我,如果我错了,这个例外只是因为.Net不想再等了,但如果我们使用连接池,这个连接可能会保持打开状态,那么sql语句可能仍然在SQL服务器端运行?或者这些系统之间存在一些隐藏的通信,无论我们是否使用连接池,都会突然停止它?

只是想知道什么是机制,它会影响SQL服务器的性能.我的意思是如果查询真的很长,如果它仍在运行需要10分钟才能运行它可能只会减慢服务器的速度,因为没有人能够得到结果.

UPDATE

所以这里我特别询问连接池,它肯定是代码将关闭与异常处理的连接,或者我们可以假设使用的代码是@dash在这里命名的首选模式.问题是如果我在该SqlConnection对象上调用Close()或Dispose()方法,它将返回到连接池,它不会在物理上关闭它.

我问它什么时候返回池,那个长查询仍然在SQL Server端运行.如果可能的话,如何避免这种情况.

再次更新

感谢@dash提到有关数据库事务的问题,是的,回滚将使它等待,我们没有关闭连接并将其返回到池中.那么,如果只是一个长期的选择查询或更新但只是一个单独的更新而不涉及任何数据库事务呢?特别是我想知道有没有一种方法可以告诉SQL Server我现在不需要结果请停止运行它?

解决方法

这完全取决于你如何执行你的查询;

想象一下以下查询:

SqlConnection myConnection = new SqlConnection("connection_string");

SqlCommand myCommand = new SqlCommand();
myCommand.Connection = myConnection;
myCommand.CommandType = CommandType.StoredProcedure;
myCommand.CommandTimeout = some_long_time;
myCommand.CommandText = "database_killing_procedure_lol";

myConnection.Open() //Connection's now open

myCommand.ExecuteNonQuery();

会发生两件事;一个是这个方法将排队,直到command.ExecuteNonQuery()完成.第二个是我们还将在方法持续时间内连接来自连接池的连接.

如果我们超时会发生什么?好吧,抛出一个异常 – 一个带有Number属性= -2的SqlException.但是,请记住,在上面的代码中,没有异常管理,所以所有会发生的事情是对象将超出范围,我们需要等待它们被处置.特别是,在这种情况发生之前,我们的连接不可重复使用.

这是以下模式首选的原因之一:

using(SqlConnection myConnection = new SqlConnection("connection_string"))
{
    using(SqlCommand myCommand = new SqlCommand())
    {

        SqlCommand myCommand = new SqlCommand();
        myCommand.Connection = myConnection;
        myCommand.CommandType = CommandType.StoredProcedure;
        myCommand.CommandTimeout = some_long_time;
        myCommand.CommandText = "database_killing_procedure_lol";

        myConnection.Open() //Connection's now open

        myCommand.ExecuteNonQuery();    

    }

}

这意味着,一旦查询完成,自然(它运行完成)或通过异常(超时或其他),资源立即返回.

在您的特定问题中,由于许多原因,需要花费很长时间才能执行大量查询.在Web应用程序中,您可能有许多用户争用有限数量的资源;内存,数据库连接,cpu时间等.因此,将这些操作与昂贵的操作捆绑在一起会降低Web应用程序的响应能力和性能,或者限制可以同时提供服务的用户数量.此外,如果数据库操作很昂贵,您也可以绑定数据库,进一步限制了性能.

由于这个原因,总是值得尝试将数据库查询的执行时间降低.如果你不能,那么你必须要小心你可以同时运行多少种类型的查询.

编辑:

所以你真的对SQL Server端发生的事情感兴趣…答案是……这取决于它! CommandTimeout实际上是一个客户端事件 – 你所说的是如果查询花费的时间超过n秒,那么我不想再等了. SQL Server被告知是这种情况,但它仍然必须处理它当前正在做的事情,因此它实际上可能需要一些时间才能完成SQL Server查询.它将尝试优先考虑这一点,但这就是它.

交易尤其如此;如果您正在运行包含在事务中的查询,并将其作为异常管理的一部分回滚,那么您必须等到回滚完成.

看到人们发生恐慌并开始针对运行查询的SQL进程ID发出KILL命令也很常见.如果命令正在运行事务,这通常是一个错误,但对于长时间运行的选择通常是可以的.

SQL Server必须管理它的状态,以使其保持一致.客户端不再监听这一事实意味着您已经浪费了工作,但SQL Server仍然需要自行清理.

所以,ASP.Net方面的一切都很好,因为它不关心,但SQL Server仍然必须完成它开始的工作,或达到可以安全地放弃工作,或回滚任何变化的点任何已打开的交易.

这显然会对数据库服务器产生性能影响,具体取决于查询!

即使是在事务之外长时间运行的SELECT或UPDATE或INSERT也必须完成. SQL Server会尽快尝试放弃它,但前提是这样做是安全的.显然,对于UPDATES和INSERT尤其如此,它必须达到数据库仍然一致的程度.对于SELECT,它会尽快结束.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读