连接关闭后,未提交的事务会发生什么?

Joh*_*nyM 43 sql sql-server transactions connection-pooling

它们会立即回滚吗?它们会在一段时间后回滚吗?他们是否处于未承诺状态?

如果使用连接池并且只是重置连接,行为是否相同?

gbn*_*gbn 25

它可以在连接池应用时保持打开状态.示例:命令超时可以保留锁和TXN,因为客户端发送为"abort".

2解决方案:

  • 在客户端测试,字面意思:

    IF @@TRANCOUNT <> 0 ROLLBACK TRAN

  • 使用SET XACT_ABORT ON以确保一个TXN被清除:问题1问题2

我总是用SET XACT_ABORT ON.

这个SQL团队博客:

请注意,对于连接池,只需在没有回滚的情况下关闭连接,只会返回到池的连接,并且事务将保持打开状态,直到以后重新使用或从池中删除.这可能导致锁定开始不必要并导致其他超时和滚动阻止

MSDN,"交易支持"部分(我的粗体)

当连接关闭时,它将根据其事务上下文释放回池中并进入相应的细分.因此,即使分布式事务仍处于挂起状态,您也可以关闭连接而不会生成错误.这允许您稍后提交或中止分布式事务.

  • 连接池在客户端发生,因此如果客户端在内部中止连接而不实际关闭它,则负责发出回滚或执行解决此问题所需的任何操作. (2认同)

Foz*_*ozi 9

未提交的更改在连接外部不可见,因此回滚的时间无关紧要.所以是的,交易最终会回滚.

  • 但它可以挂起其他连接(等待提交/回滚),具体取决于您的隔离,因此时间仍然很重要. (9认同)
  • 正确,但重点是"最终",这是一件坏事* (3认同)

Rem*_*anu 6

当会话关闭时,服务器将立即回滚任何未通信的事务.
在将事务返回到池之前,ADO池可用于清除任何未通信的事务.如果您处置与挂起事务的连接,它将回滚.

客户端可以使用ADO API(SqlConnection.BeginTransaction)或执行BEGIN TRANSACTION语句来启动事务.客户端和服务器之间的TDS协议具有特殊令牌,通知客户端何时启动/提交事务,因此ADO知道连接具有挂起的事务,即使它们是以T-SQL代码启动的.