【问题标题】:Should I ignore an exception on database insert?我应该忽略数据库插入的异常吗?
【发布时间】:2010-11-22 04:39:54
【问题描述】:

我有两个表 A 和 B 以及一个简单的表 X,它维护两者之间的关系。 X 包含 AID 和 BID 作为其主键。

我正在使用 Linq-to-Sql 插入如下关系:

public void InsertRelationship(int y, int z) {
  DataContext.X.InsertOnSubmit(new x { AID = y; BID = z });
}

问题是在极端情况下可以调用两次对 InsertRelationship() 的调用,因此会由于重复记录而引发异常。这对我来说无关紧要,因为我知道这种关系存在,所以我忽略了这个例外。

在这种情况下可以忽略异常还是仍然是不好的做法?我是否应该在插入之前检查该关系是否不存在?这将如何影响性能?

更新

无法避免重复调用 InsertRelationship()。它是一个 Web 应用程序,因此我无法阻止用户打开两个单独的窗口并调用该方法两次。该方法不会通过典型的用户交互被调用两次,但我在这里针对极端情况进行编程。重复的百分比可能会非常低,但我还不能确定确切的数字。

【问题讨论】:

    标签: sql linq-to-sql exception


    【解决方案1】:

    忽略异常的主要问题是,对于与您不想隐藏的重复记录完全不相关的其他问题,可能会引发异常,例如 SQL 超时或死锁等。

    最好的解决方案是构建您的应用程序,这样就不会发生欺骗插入,下一个最好的方法是在插入之前检查它们是否存在。

    如果性能至关重要,则无法避免重复插入,重复插入与工作插入的比率非常小,并且您可以看出引发的异常只是由于重复问题,您最好只捕获例外并忽略它。但这是一个有很多条件的 if :-)

    【讨论】:

      【解决方案2】:

      一般来说,你应该先检查。

      但可能更准确地说,您应该构建应用程序的接口,这样它就不会出现通过典型的用户交互甚至可能生成您需要检查的情况的情况.

      不管怎样,更好的做法是检查。

      【讨论】:

      • 由于这是一个 Web 应用程序,我无法避免用户调用该方法两次的可能性。我已更新问题以显示这一点。
      • 正如我所说,无论如何,最好检查并返回一个不错的错误给他们。
      【解决方案3】:

      就性能而言,抛出异常代价高昂。此外,您得到的异常不能保证每次都是出于相同的原因。您应该始终在再次添加之前检查该行是否存在,因为您知道问题可能从一开始就存在。

      例外是针对特殊情况 - 这不是例外,这是创建数据的正常流程的一部分。

      【讨论】:

      • “抛出异常很昂贵”,是否比每次检查记录不存在更昂贵?重复调用的数量可能不到 2%。
      • 除非您有确凿的证据表明首先检查数据库实际上会导致该区域出现问题,否则我不会担心性能 - 在那之前,您在这方面所做的任何事情都是过早的优化。首先检查是遵循的最佳模式,因为代码的意图很明确,而且您不会通过忽略异常来隐藏信息。
      【解决方案4】:

      虽然不太可能,但检查然后插入记录不是竞争条件吗?如果是这样,您应该针对它进行防御性编程,这意味着捕获并检查任何异常。

      在这种情况下,您应该在选择忽略它之前检查异常的类型和/或它的潜在错误编号。这样,您可以只忽略与尝试插入重复记录相关的异常(可能违反主键约束)。您需要以不同的方式处理其他类型的异常。

      【讨论】:

        【解决方案5】:

        如果您确定记录没有被插入只是因为它已经存在,那应该没问题。其他明智的忽略异常可能会隐藏其他危险。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-07-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-08-27
          • 2012-06-04
          相关资源
          最近更新 更多