断开网络连接会停止查询吗?


13

我最近对100,000条记录执行了更新查询。我意识到在查询运行时我犯了一个错误,并迅速拔下了网络电缆。

更新查询吗

  1. 停止处理并完全回滚?
  2. 继续处理以完成并提交?
  3. 停止处理,只保留部分目标行更新?

2
查询到达服务器后,它将继续进行,除非您在服务器上取消了查询。
JP Chauhan


1
马丁的评论为您的问题robocop提供了直接答案。如果网络查询完成运行之前通知断开连接的SQL Server,则SQL Server将回滚断开连接。否则,如果在SQL Server被告知存在网络断开连接之前查询已完成,则它将被提交。在任何情况下(假设您编写了一个更新查询),SQL Server都不会执行部分更新。
Nick Chammas

Answers:


22

如Nick和Martin所述,查询的最终状态取决于SQL Server在查询完成之前是否知道您的网络电缆拔出情况。从在线丛书中(尽管我发现有趣的是,在2000年2005年2008年和2008 R2中有与此相对应的主题,但在2012年或2014年则没有):

如果错误阻止事务成功完成,则SQL Server将自动回滚该事务并释放该事务持有的所有资源。如果客户端与数据库引擎实例的网络连接断开,则当网络通知中断实例时,该连接的所有未完成事务都会回滚。如果客户端应用程序失败,或者客户端计算机关闭或重新启动,这也会断开连接,并且数据库引擎实例会在网络通知断开连接时回滚所有未完成的连接。如果客户端注销该应用程序,则所有未完成的事务都会回滚。

(顺便说一句,最后第二句中的“ 连接”一词可能是交易。我不知道该如何回滚连接。)

以类似的方式,SQL Server可能会在意外关闭服务器后在恢复过程中撤消或重做事务,这将取决于关闭时事务的状态。我已经看到人们使用这种策略来实现您想要做的事情(取消事务),并且当服务器再次启动时,很多工作都只是简单地重做了(因此,他们下意识的反应的净效果要近得多)达到比预期的零)。

因此,我建议您将来最好对在重要系统上运行即席查询有更好的纪律,而不是慌乱地做一些大胆的事情(例如拉动网络电缆或关闭机器)。例如,代替:

UPDATE dbo.sometable 
-- where *oops* I forgot this part

拥有这个:

BEGIN TRANSACTION;

UPDATE dbo.sometable
-- where *oops* I forgot this part

-- COMMIT TRANSACTION;
-- ROLLBACK TRANSACTION;

然后,如果更新确实正确,则可以突出显示该COMMIT零件并运行它。如果不是,您可以冷静地突出显示该ROLLBACK零件并运行它。您甚至可以使用SSMS工具包之类的加载项来编辑New Query模板以包括该样板。

现在,如果您运行查询然后又不提交也不回滚,它仍然可能使您遇到麻烦,因为现在您的事务正在阻止其他用户。但是,这比不可撤销地修改数据更好。

当然,像往常一样,有一个可以依靠的备份。


5
这是极好的建议,可以解决OP问题的根源,但实际上并不能回答查询是否继续运行的问题。
Nick Chammas

3
感谢@Nick,我的动机是解决原因(引起问题),而不是症状,但是我更新了答案。
亚伦·伯特兰

8

@亚伦是正确的。最好在命令之前创建事务。如果您不记得要这样做,那么一种选择是进入Tools-Options设置并打开SET IMPLICIT_TRANSACTIONS。一旦运行某些命令,这将自动启动事务。其中包括UPDATEDELETE等等。这似乎是将要执行的所有命令的相当完整的列表"change"SELECT也包含在列表中并will开始交易。您可以在此处看到启动此设置的事务的命令的完整列表。如果已经开始,则不会创建事务。现在不利的一面是,COMMIT进行任何更改后您都必须记住。

注意:基于@Aaron的建议,我将再次强调这一点。

This is very important!  You will have to remember to COMMIT after any change made!

基本上,您是在忘了BEGIN一笔交易并弄乱了一些东西,而忘了COMMIT一笔交易,如果您先将其保留为开盘,然后将其保留一天,则可以将其挂起。我确实测试了只是关闭一个查询窗口,以为它会回滚我的事务,但是确实提示我是否要提交或回滚该事务。

在此处输入图片说明


实际上:SELECT 开始一笔交易(在您发布的链接中也有记录)
a_horse_with_no_name 2013年

感谢@a_horse_with_no_name抓住了它!我没有足够仔细地阅读,并且已经过时了(显然是错误的)。
肯尼斯·费希尔

1
这是一个很有帮助的帖子,但实际上并不能回答OP是否继续运行查询的问题。
Nick Chammas

2
这是对@Aaron答案的补充。简而言之,就是发表评论。
肯尼斯·费舍尔

2

我认为这真的取决于:

如果在拔出网络电缆之前该命令已经到达服务器,则该命令仍将继续正常执行。

如果您有一个TransactionScope(用于.Net,不确定其他语言)用于封装所有更新命令,则只有在未执行transactionScope.Complete()但不能保证的情况下,才可以停止提交事务。 。


2
您说:“如果在拔出网络电缆之前该命令已经到达服务器,该命令仍将继续正常执行。” Martin链接到上面的SQL Server BOL页面与这矛盾。请参阅“事务处理期间的错误”
Nick Chammas

你是对的。如果指定了事务,该命令将自动回滚。但是根据我们的经验,当没有明确指定任何事务时,即使我们在中间停止了我们的应用程序,该命令(没有事务的批处理更新)也已完全执行,这实际上断开了连接-但这实际上不是一个很好的例子可能是不正确的。对此做一些测试可能很好
Rex
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.