它们是否会立即回滚? 还是在一段时间后回滚? 它们是否被保留在未提交状态?
如果使用连接池并且连接只是重置,那么行为是否相同?
它们是否会立即回滚? 还是在一段时间后回滚? 它们是否被保留在未提交状态?
如果使用连接池并且连接只是重置,那么行为是否相同?
连接池应用时可保持打开状态。例如:命令超时会因客户端发送“abort”而保留锁定和 TXN(事务)。
两种解决方案:
在客户端中进行测试:
IF @@TRANCOUNT <> 0 ROLLBACK TRAN
使用SET XACT_ABORT ON
确保 TXN 被清除:Question 1 和 Question 2
我总是使用 SET XACT_ABORT ON
。
来自SQL Team博客:
请注意,在连接池中,仅关闭连接而不回滚将只返回连接到池中,并且事务将保持打开状态,直到稍后重用或从池中删除。这可能导致锁定保持不必要并引起其他超时和滚动块。
来自MSDN,“事务支持” 部分(我加粗了):
关闭连接时,它会被释放回池中,并根据其事务上下文放入适当的子部分中。因此,您可以关闭连接而不生成错误,即使仍有分布式事务待处理。这使您可以在稍后的时间提交或中止分布式事务。
未提交的更改在连接之外是不可见的,因此回滚的时间无关紧要。因此,事务最终会被回滚。
ISOLATION LEVEL READ UNCOMMITTED
,在新连接中会读取到我的未提交更改吗? - Barak当会话关闭时,服务器将立即回滚任何未提交的事务。
ADO池负责在将事务返回给池之前清除任何未提交的事务。如果您处置了具有挂起事务的连接,则会回滚该事务。
客户端可以使用ADO API(SqlConnection.BeginTransaction)启动事务,也可以通过执行BEGIN TRANSACTION语句来启动事务。客户端和服务器之间的TDS协议具有特殊的令牌,通知客户端何时开始/提交事务,因此即使在T-SQL代码中启动它们,ADO也知道连接具有挂起的事务。