SQL 当连接关闭时,未提交的事务会发生什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1539564/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What happens to an uncommitted transaction when the connection is closed?
提问by JohnnyM
Are they rolled back immediately? Are they rolled back after some period of time? Are they left in an uncommitted state?
他们会立即回滚吗?他们在一段时间后回滚了吗?他们是否处于未提交状态?
Is the behavior the same if connection pooling is used and the connections are simply reset?
如果使用连接池并且只是重置连接,行为是否相同?
采纳答案by gbn
It can stay open while connection pooling applies. Example: command timeout can leave locks and TXN because the client sends as "abort".
它可以在连接池应用时保持打开状态。示例:命令超时可以留下锁和 TXN,因为客户端发送为“中止”。
2 solutions:
2个解决方案:
Test in the client, literally:
IF @@TRANCOUNT <> 0 ROLLBACK TRAN
Use
SET XACT_ABORT ON
to ensured a TXN is cleaned up: Question 1and Question 2
I always use SET XACT_ABORT ON
.
我总是使用SET XACT_ABORT ON
.
From this SQL Team blog:
Note that with connection pooling, simply closing the connection without a rollback will only return the connection to the pool and the transaction will remain open until later reused or removed from the pool. This can result in locks begin held unnecessary and cause other timeouts and rolling block
请注意,对于连接池,只需在没有回滚的情况下关闭连接只会将连接返回到池中,并且事务将保持打开状态,直到稍后重用或从池中删除。这可能会导致不必要的锁开始持有并导致其他超时和滚动块
From MSDN, section "Transaction Support" (my bold)
来自MSDN 的“事务支持”部分(我的粗体)
When a connection is closed, it is released back into the pool and into the appropriate subdivision based on its transaction context. Therefore, you can close the connection without generating an error, even though a distributed transaction is still pending. This allows you to commit or abort the distributed transaction at a later time.
当连接关闭时,它会被释放回池中,并根据其事务上下文进入适当的细分。因此,即使分布式事务仍处于挂起状态,您也可以关闭连接而不会产生错误。这允许您稍后提交或中止分布式事务。
回答by Fozi
Uncommitted changes are not visible outside of the connection, so the time of the rollback is irrelevant. So yes, the transaction is eventually rolled back.
未提交的更改在连接外部不可见,因此回滚的时间无关紧要。所以是的,事务最终会回滚。
回答by Remus Rusanu
The server will rollback immedeatly any uncommited transaction when a session is closed.
The ADO pool is reponsible for clearing any uncommited transaction before returning a transaction to the pool. If you dispose a connection with pending transactions, it will rollback.
当会话关闭时,服务器将立即回滚任何未提交的事务。
ADO 池负责在将事务返回池之前清除任何未提交的事务。如果您使用挂起事务处理连接,它将回滚。
Transactions can be started by the client using the ADO API (SqlConnection.BeginTransaction) or by executing an BEGIN TRANSACTION statement. The TDS protocol between client and server has special tokens informing the client when a transaction was started/commited like this so ADO knows that the connection has pending transactions even if they are started in T-SQL code.
客户端可以使用 ADO API (SqlConnection.BeginTransaction) 或通过执行 BEGIN TRANSACTION 语句来启动事务。客户端和服务器之间的 TDS 协议具有特殊的令牌,通知客户端事务何时开始/提交,因此 ADO 知道连接有挂起的事务,即使它们是在 T-SQL 代码中启动的。