C# 重试失败的System.Data.SqlClient操作的干净方法

C# 重试失败的System.Data.SqlClient操作的干净方法,c#,.net,sql,sql-server-2008,C#,.net,Sql,Sql Server 2008,我继承了一个相当大的C#代码库,它以以下方式执行DB操作,被乱扔了数百次: using (SqlConnection connection = new SqlConnection(connectionString)) { SqlCommand command = new SqlCommand(queryString, connection); command.Connection.Open(); command.ExecuteNonQuery(); } 但是,由于我无法

我继承了一个相当大的C#代码库,它以以下方式执行DB操作,被乱扔了数百次:

using (SqlConnection connection = new SqlConnection(connectionString)) {
    SqlCommand command = new SqlCommand(queryString, connection);
    command.Connection.Open();
    command.ExecuteNonQuery();
}
但是,由于我无法控制的因素,DB服务器非常糟糕,特别容易出现故障,因此这些查询中有很大一部分会失败。鉴于这种访问数据库的特殊方式在代码中随处可见,我如何在一个地方编写重试代码,并在使用
SqlCommand
的任何地方应用它

一些想法:

  • 我试图重写
    SqlConnection
    /
    SqlCommand
    ExecuteNonQuery
    ,以便创建包装器版本。不好
    SqlConnection
    SqlCommand
    是密封的C#对象
  • 我可以创建一个名为
    MySqlConnection
    的容器类,其中包含一个.NET
    SqlConnection
    对象,然后创建我自己的
    ExecuteNonQuery
    ,然后重试
    SqlCommand.ExecuteNonQuery()
    。然而,这并不好,因为我必须实现每一个
    SqlCommand
    函数,并训练其他人使用我的包装类,而不是直接使用
    SqlCommand
    。不幸的是,在这种情况下,用户教育不是一个可接受的解决方案。我被其他外包的开发人员困住了,他们经常离职,而且永远不会听从我使用新SQL类的请求
  • 正如我前面提到的,我只是无法(从政治上和技术上)使用DB层。问题的根本原因只是一个糟糕的SQL server设置,但我无法在该级别解决问题

还有其他选择吗?

假设一点2x4和一张给外包“合作伙伴”的机票是不可能的

你可能想看看像postsharp这样的东西(http://www.sharpcrafters.com/)生成面向方面的解决方案。基本上,编写一些代码来连接各种方法。然后可以在SqlCommand上连接事件;如果你运气好的话,信息和状态的改变可以产生一些有用的东西

我想说,说服您的经理正确的代码修复的最佳解决方案是唯一明智的解决方案。我非常了解您的痛苦,但是任何允许他人编写软件的公司都需要能够负责验证该软件的质量,或者准备好忽略低质量并接受后果

识别真正糟糕的SQL性能代码,看看这是否可以释放一些SQL server资源,这可能会有一定的帮助


祝你好运

你有没有想过简单实用的方法可以满足你的需要,并成为进行DB调用的标准?尽管这与你的想法一致,但它不允许来自海外团队的阻力,因为他们不必使用不同的类型。这可能只是将作品抽象到一个地方的一个原因

我们需要集中我们的数据库处理,等等…向管理层说一些花哨的话…然后你就走了


似乎你可以从政治立场上实现这一点不?

如果你能负担得起开销,一个选择就是编写某种“DB代理”

您的代码将指向代理(通过其连接字符串)。代理将依次指向实际的数据库(通过其连接字符串)。代理将拦截数据库请求,在实际数据库上执行它们,并返回结果。但在这样做时,它可以实现一种算法,使查询更加可靠(通过实现重试等)


只是说说而已。这将是一种在不改变所有代码的情况下实现重试的方法。

顺便说一句,您还需要在
SqlCommand
周围使用
。另外,仅供参考,
SqlClient
与C#无关-它是.NET的一部分。实际上没有必要处理SqlCommand。它派生自IDisposable的唯一原因是它派生自Component。Component的Dispose功能是将Component从其父站点中移除。所有这些都是为了将所有东西拖放到表单群组(即VB类型)上。