断开网络会停止查询吗?

rob*_*cop 15 sql-server network

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

是否更新查询

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

Aar*_*and 22

正如 Nick 和 Martin 所提到的,您的查询的最终状态取决于 SQL Server 在查询完成之前是否知道您的网络电缆已拔出。来自在线图书(尽管我觉得有趣的是,在2000200520082008 R2中有与此相同的主题,但没有 2012 或 2014):

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

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

类似地,SQL Server 在服务器意外关闭后的恢复过程中可能会撤消或重做事务,这取决于关闭时事务的状态。我已经看到人们使用这种策略来实现你想要做的事情(取消事务),当服务器再次启动时,大部分工作只是重做(所以他们下意识反应的净效应更接近)比他们预期的要零)。

因此,与其受制于这一点,不如在恐慌中做一些激烈的事情,例如拔掉网线或关闭机器,我建议您将来在对重要系统运行临时查询方面有更好的纪律。例如,而不是:

UPDATE dbo.sometable 
-- where *oops* I forgot this part
Run Code Online (Sandbox Code Playgroud)

有这个:

BEGIN TRANSACTION;

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

-- COMMIT TRANSACTION;
-- ROLLBACK TRANSACTION;
Run Code Online (Sandbox Code Playgroud)

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

现在,如果您运行查询然后提交或回滚,它仍然会给您带来麻烦,因为现在您的事务正在阻止其他用户。但这比不可撤销地修改数据要好。

当然,一如既往,有一个您可以依赖的备份。

  • 这是一个很好的建议,解决了 OP 问题的根源,但它实际上并没有回答查询是否继续运行的问题。 (5认同)
  • 谢谢@Nick,我的动机是解决原因(引发问题),而不是症状,但我已经更新了我的答案。 (3认同)

Ken*_*her 8

@Aaron 是正确的。在您发出命令之前创建交易是您最好的选择。如果您不记得这样做,那么一种选择是进入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!
Run Code Online (Sandbox Code Playgroud)

基本上,您正在权衡忘记BEGIN交易和搞砸某些事情,因为忘记COMMIT交易并在您将其打开然后离开一天时将其挂起。我做了测试,只是关闭了一个查询窗口,认为它会回滚我的事务,但是它确实提示我是否要提交或回滚事务。

在此处输入图片说明

  • 这是对@Aaron 答案的补充。发表评论太多了。 (2认同)

小智 2

我认为这确实取决于:

如果在拔掉网线之前该命令已经到达服务器,该命令仍将继续正常执行。

如果你有一个 TransactionScope(在 .Net 中使用,不确定其他语言)来封装所有更新命令,那么只有在 transactionScope.Complete() 尚未执行时,你可能才能停止事务提交,但不能保证。 。

  • 你说“如果在你拔掉网线之前命令已经到达服务器,命令仍然会继续正常执行”。这与 Martin 上面链接的 SQL Server BOL 页面**矛盾**。请参阅[“事务处理期间的错误”](http://msdn.microsoft.com/en-us/library/ms175523.aspx)。 (2认同)