【问题标题】:Is it safe to retry a command/connection timeout?重试命令/连接超时是否安全?
【发布时间】:2013-08-07 11:27:21
【问题描述】:

我们已经使用一种机制(一个名为SqlDeadlockHelper 的类)已经有一段时间了,它在尝试由于死锁而失败的数据库调用时帮助了我们很多。 SqlDeadlockHelper 会捕捉到SqlException,认识到这是一个死锁,然后再试一次。第二次尝试几乎总是成功。

对命令和/或连接超时执行此类操作是否安全?我的意思是,在 SQL Server 上完成工作是不可能的,只能在数据返回给调用者之前超时,是吗?

编辑:

事务已被提及作为将调用视为工作单元的一种方式。这样它就可以成功或完全回滚。但是,一个只做一件事的 ADO.NET 调用又如何呢?是否有必要将其包装在事务中?

【问题讨论】:

  • 我不明白为什么不...

标签: c# sql-server timeout


【解决方案1】:

根据您的工作单元,SQL 有可能在死锁和引发错误之前完成部分工作。您处理工作单元的方式是使用事务。大多数 SQL 数据库都支持事务。您需要将工作单元包装在 Begin、Commit 和 Rollback 事务中。

http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqltransaction.aspx

【讨论】:

  • 所以这也应该适用于超时?关键是使用事务。如果交易失败,重试是安全的。如果它不在事务中,而只是直接的 ADO.NET 调用怎么办?可以重试吗?
  • 没错,它适用于所有 SQL 命令。如果命令不在事务中,则不能保证“单一”工作单元,这可能导致部分数据提交。事务是一个 SQL 概念,旨在处理您遇到的场景以及其他场景。下面是使用 ADO 事务的示例。 msdn.microsoft.com/en-us/library/aa227162(v=VS.60).aspx
【解决方案2】:

来自TechNet Library

检测到死锁后,数据库引擎通过以下方式结束死锁 选择其中一个线程作为死锁牺牲品。数据库引擎 终止正在为线程执行的当前批处理,回滚 死锁受害者的事务,并返回 1205 错误 应用程序。为死锁受害者回滚事务 释放事务持有的所有锁。这允许 其他线程的事务被解除阻塞并继续。 1205死锁牺牲品错误记录有关线程的信息 以及错误日志中涉及死锁的资源。

因此,您的事务已安全回滚,您可以再试一次。

编辑

作为一个懒惰的a**e,我没有仔细阅读您的问题。 让我们看看:

对命令和/或连接超时执行此类操作是否安全?

我不会做同样的概括,因为您最终可能会尝试从根本无法访问的数据库中读取数据。您应该有最大的重试次数。

我的意思是,不可能在 SQL Server 上完成工作,只能 在数据返回给调用者之前超时,是吗?

从未听说过,如果您使用事务,这应该是不可能的。您应该使用它们以及 XACT_ABORT,Specifies whether SQL Server automatically rolls back the current transaction when a Transact-SQL statement raises a run-time error. 的标志但是,工作可能既未完成也未完成 - 请参阅 zombie transaction

I just found this as well.

【讨论】:

  • 这是一个僵局。我问的是超时。
  • 谢谢。请参阅我的编辑。我之所以问,是因为我们有一个现有的应用程序,其中有很多单一的 ADO.NET 调用。我需要知道是否有必要将所有这些都包含在事务中。
  • 不,如果你的代码是单个TSQL语句,你不必用事务包装它,它默认是自动提交的。
猜你喜欢
  • 2010-11-28
  • 2017-07-02
  • 1970-01-01
  • 2012-09-01
  • 1970-01-01
  • 2012-05-23
  • 1970-01-01
  • 1970-01-01
  • 2010-09-29
相关资源
最近更新 更多