gpt4 book ai didi

c# - SqlCommand.ExecuteReader() 在死锁时不会抛出 SqlException

转载 作者:行者123 更新时间:2023-11-30 21:55:27 34 4
gpt4 key购买 nike

我们使用 C# SqlCommand.ExecuteReader() 在事务中发出 SQL Server 存储过程和 SQL 请求。

当连接被选为死锁牺牲品时,ExecuteReader() 不会为某些命令抛出带有 1205 死锁代码的 SqlException,但会为其他命令抛出。

根据 MSDN

If a transaction is deadlocked, an exception may not be thrown until Read is called.

考虑到我们使用封装在我们自己的数据库请求框架中的SqlCommand对象,有没有办法始终保证在发生死锁时抛出异常?

我们正在使用 .Net 4.5、SQL Server 2008 R2、Visual Studio 2012

这是我们的数据库访问框架代码的简化版本:

SqlDataReader DoWork( string sql ) {
...
cmd = new SqlCommand( sql );
SqlDataReader rdr = null;

try {
rdr = cmd.ExecuteReader( CommandBehavior.Default );
} catch (SqlException sqle) {
// Log the error, throw a custom exception, etc.
// if (sqle.ErrorCode == 1205) ...
...
if (rdr != null) {
rdr.Close();
rdr = null;
}
}
// All is well, so just return to caller to consume the result set
return rdr;
}

...

main() {
...
SqlDataReader result = DoWork( "select ...";

if (result.HasRows) { // Check there is data to read...
while (result.Read()) {
...
}
result.Close();
...
}

最佳答案

我不知道你为什么这样做:

if (result.HasRows)

这不是必需的,它可以防止出现死锁:

If a transaction is deadlocked, an exception may not be thrown until Read is called.

删除那个if。这是一种常见的反模式。它通常是由复制示例代码但没有真正理解它的作用的人引入的。

catch 中的这也是一个反模式:

    if (rdr != null) {
rdr.Close();
rdr = null;
}

只需使用using

关于c# - SqlCommand.ExecuteReader() 在死锁时不会抛出 SqlException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32279241/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com