如何捕获 SQLServer 超时异常
Posted
技术标签:
【中文标题】如何捕获 SQLServer 超时异常【英文标题】:How to catch SQLServer timeout exceptions 【发布时间】:2010-09-06 23:28:14 【问题描述】:我需要专门捕获 SQL Server 超时异常,以便以不同方式处理它们。我知道我可以捕获 SqlException,然后检查消息字符串是否包含“超时”,但想知道是否有更好的方法?
try
//some code
catch (SqlException ex)
if (ex.Message.Contains("Timeout"))
//handle timeout
else
throw;
【问题讨论】:
您是在寻找 ConnectionTimeout 还是 CommandTimeout,即您希望连接失败还是执行的命令失败? 我正在寻找一个 CommandTimeout,我认为它默认设置为 30 秒 【参考方案1】:SqlException.ErrorCode 属性的值是多少?你能用它吗?
当出现超时时,可能值得检查 -2146232060 的代码。
我会在您的数据代码中将其设置为静态常量。
【讨论】:
查看错误代码的文档,在我看来,它报告了互操作级别的错误。因此,它可能更多是在 COM 错误级别上,或者提供商遇到了异常(通常),而不是与您正在执行的操作相关的特定错误。 @Eric 是正确的 - 这是 SqlException 类型的 HRESULT 代码,而不是异常源。【参考方案2】:要检查超时,我相信您检查 ex.Number 的值。如果是-2,那么你有超时情况。
-2 是超时的错误代码,从 SQL Server 的 MDAC 驱动程序 DBNETLIB 返回。这可以通过下载Reflector 并在 System.Data.SqlClient.TdsEnums 下查看 TIMEOUT_EXPIRED 来查看。
你的代码会这样写:
if (ex.Number == -2)
//handle timeout
演示失败的代码:
try
SqlConnection sql = new SqlConnection(@"Network Library=DBMSSOCN;Data Source=YourServer,1433;Initial Catalog=YourDB;Integrated Security=SSPI;");
sql.Open();
SqlCommand cmd = sql.CreateCommand();
cmd.CommandText = "DECLARE @i int WHILE EXISTS (SELECT 1 from sysobjects) BEGIN SELECT @i = 1 END";
cmd.ExecuteNonQuery(); // This line will timeout.
cmd.Dispose();
sql.Close();
catch (SqlException ex)
if (ex.Number == -2)
Console.WriteLine ("Timeout occurred");
【讨论】:
是的,这就是我目前正在做的事情,但检查 -2 并不是很优雅 下载Red Gate的Reflector,搜索TIMEOUT_EXPIRED。它位于 System.Data.SqlClient.TdsEnums 中,其值为 -2。 :o) 对于没有使用Reflector的人:link @brodie 这就是为什么你应该为它创建一个常量,你可以在常量的评论中解释“神奇”值的来源。【参考方案3】:这里:http://www.tech-archive.net/Archive/DotNet/microsoft.public.dotnet.framework.adonet/2006-10/msg00064.html 您还可以阅读 Thomas Weingartner 写道:
超时:SqlException.Number == -2(这是 ADO.NET 错误代码) 一般网络错误:SqlException.Number == 11 死锁:SqlException.Number == 1205(这是 SQL Server 错误代码)
...
我们也将“一般网络错误”作为超时异常处理。它仅在极少数情况下发生,例如当您的更新/插入/删除查询将引发长时间运行的触发器时。
【讨论】:
【参考方案4】:为 c# 6 更新:
try
// some code
catch (SqlException ex) when (ex.Number == -2) // -2 is a sql timeout
// handle timeout
非常简单好看!!
【讨论】:
谢谢...我喜欢你的建议并使用它。【参考方案5】:我不确定,但是当我们执行超时或命令超时时 客户端向 SQL Server 发送“ABORT”,然后简单地放弃查询处理。没有事务回滚,没有锁被释放。为了解决这个问题,我在存储过程中删除事务并在我的 .Net 代码中使用 SQL 事务来管理 sqlException
【讨论】:
【参考方案6】:当客户端发送 ABORT 时,不会回滚任何事务。为了避免这种行为,我们必须使用 SET_XACT_ABORT ON https://docs.microsoft.com/en-us/sql/t-sql/statements/set-xact-abort-transact-sql?view=sql-server-ver15
【讨论】:
它没有回答如何在 c# 代码中捕获命令超时的问题以上是关于如何捕获 SQLServer 超时异常的主要内容,如果未能解决你的问题,请参考以下文章
如何将java程序里的一段连接mysql的语句转为连接sqlserver语句。连接的是sqlser