在Sql Server Profiler中,“exec sp_reset_connection”是什么意思?

186

尝试理解Sql Profiler通过"sp_reset_connection"发出的含义。

我有以下代码:在BatchStarting和Completed之间,有一行"exec sp_reset_connection"。

RPC:Completed       exec sp_reset_connection
SQL:BatchStarting   SELECT [c].[TestID] AS [TestID], [c].[Description] AS [Description] FROM [dbo].[Test] AS [c]
SQL:BatchCompleted  SELECT [c].[TestID] AS [TestID], [c].[Description] AS [Description] FROM [dbo].[Test] AS [c]    
基本上第一行的 "exec sp_reset_connection" 的意思是整个过程(我的连接被打开,select语句运行,然后连接关闭并释放回池中)已经发生了吗?还是我的连接仍处于打开状态?
另外,为什么在我自己的选择语句之前执行 "sp_reset_connection",难道不应该在用户的 SQL 之后进行重置吗?
我想知道是否有一种更详细的方法来了解连接何时打开和关闭?
通过看到 "exec sp_reset_connection",这是否意味着我的连接已关闭?
3个回答

214

就像其他答案所说的那样,sp_reset_connection表示连接池正在被重用。请注意一个特定的后果!

Jimmy Mays' MSDN Blog说:

sp_reset_connection不会将事务隔离级别重置为服务器默认值,而是保留上一个连接的设置。

更新:从SQL 2014开始,对于TDS版本为7.3或更高版本的客户端驱动程序,事务隔离级别将被重置回默认值。

参考:SQL Server: Isolation level leaks across pooled connections

以下是一些额外的信息:

sp_reset_connection是做什么的?

数据访问API层,如ODBC、OLE-DB和System.Data.SqlClient都会在重用连接池中的连接时调用(内部)存储过程sp_reset_connection。它会在重新使用连接之前重置连接的状态,但是没有文档记录哪些内容被重置。本文试图记录被重置的连接部分。

sp_reset_connection将重置连接的以下方面:

  • 所有错误状态和编号(如@@error)

  • 停止执行并行查询的父EC的所有EC(执行上下文)的子线程

  • 等待任何未完成的I/O操作

  • 释放连接在服务器上持有的任何保留缓冲区

  • 解锁连接使用的任何缓冲区资源

  • 释放连接拥有的所有已分配内存

  • 清除连接创建的所有工作或临时表

  • 终止连接拥有的所有全局游标

  • 关闭所有打开的SQL-XML句柄

  • 删除所有打开的与SQL-XML相关的工作表

  • 关闭所有系统表

  • 关闭所有用户表

  • 删除所有临时对象

  • 中止打开的事务

  • 在注册时从分布式事务中退出

  • 减少当前数据库中用户的引用计数,释放共享数据库锁

  • 释放已获取的锁

  • 释放已获取的句柄

  • 将所有SET选项重置为默认值

  • 重置@@rowcount值

  • 重置@@identity值

  • 使用dbcc traceon()重置任何会话级跟踪选项

  • 在SQL Server 2005及更高版本中,将CONTEXT_INFO重置为NULL [不是原始文章的一部分]

sp_reset_connection不会重置:

  • 安全上下文,这就是为什么连接池基于完全相同的连接字符串匹配连接的原因

  • 使用sp_setapprole输入的应用程序角色,因为在SQL Server 2005之前根本无法还原应用程序角色。从SQL Server 2005开始,可以使用不属于会话的其他信息还原应用程序角色。在关闭连接之前,需要使用在执行sp_setapprole时捕获的“cookie”值通过sp_unsetapprole手动还原应用程序角色。

注意:我在这里包含列表,因为我不想让它在瞬息万变的网络中丢失。


18
感谢您包含了必要的信息。您提供的第二个链接目前已失效。 - Nick Chammas
15
它还会引起“审核登录/审核注销”事件,在 SQL Server Profiler 中显示,并触发相关触发器事件。看起来客户端断开连接并重新连接了,但实际上并没有。这让我困惑了一段时间,所以我想让大家知道。 - Martin
1
它会重置我放入 CONTEXT_INFO 中的内容吗? - Robert Niestroj
3
较早版本的SQL Server(至少包括SQL Server 2000)没有重置CONTEXT_INFO,这导致我们在处理任何连接之前必须手动清除CONTEXT_INFO。最近我注意到,至少SQL Server 2008 R2已经修复了这个bug,CONTEXT_INFO现在会被自动清除。 - Ian Boyd
2
@IanBoyd 我刚刚测试了 SQL Server 2005 SP3,它确实将 CONTEXT_INFO 重置为 NULL。我会在答案中更新这个细节。而且值得一提的是,我确认 TRANSACTION ISOLATION LEVEL 没有被重置。 - Solomon Rutzky
显示剩余7条评论

23

这是一个指示正在使用连接池的迹象(这是一件好事)。


10

请注意:

如果您在存储过程或触发器中使用 SET TRANSACTION ISOLATION LEVEL,当该对象返回控制权时,隔离级别将重置为调用该对象时生效的级别。例如,如果您在批处理中设置了 REPEATABLE READ,并且该批处理随后调用一个将隔离级别设置为 SERIALIZABLE 的存储过程,则当存储过程将控制权返回给批处理时,隔离级别设置将恢复为 REPEATABLE READ。

http://msdn.microsoft.com/en-us/library/ms173763.aspx


6
如果你在客户端使用客户端方法进行同样的操作,它不会重置... - Softlion

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接