2009-08-24 40 views
2

我有两个表,A和B和一个简单的表X,它们保持两者之间的关系。 X包含AID和BID作为其主键。我应该忽略数据库插入的异常吗?

我使用LINQ到SQL插入像一个关系:

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

的问题是,两次调用InsertRelationship()可在极端情况下调用这样一个异常会因抛出重复的记录。这对我来说并不重要,因为我知道这种关系是存在的,所以我忽略了这个例外。

是否还好忽略这种情况下的例外或者是它仍然不好的做法?我应该在插入之前检查关系是否已经存在?这会如何影响性能?

更新

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

回答

2

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

最好的解决办法是构建应用程序,以便将受骗者插入不会发生,下一个最好的是做插入之前检查它们的存在。

如果性能至关重要,无法避免死锁插入,死锁插入与工作插入的比例非常小,并且您可以知道引发的异常只是由于重复问题所致,您可能更适合捕获例外并忽略它。但是,这是一个如果与很多条件:-)

2

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

但可能更准确的说,是你要构建的界面应用程序,使得它不存在它甚至有可能,通过典型的用户交互的情况下,甚至产生你需要的情况下检查。

无论如何,更好的做法是检查。

+0

由于这是一个Web应用程序,我无法避免用户可能调用该方法两次的可能性。我已经更新了这个问题。 – 2009-08-24 07:49:44

+0

正如我所说,无论如何,最好检查并向他们返回一个不错的错误。 – 2009-08-24 07:51:06

0

如果您确信不仅是因为它已经存在,应该没关系的记录未插入。其他明智的忽略异常可能会隐藏其他危险。

2

就性能而言,投掷异常很昂贵。另外,你所得到的例外永远不会保证每次都有相同的原因。您应该始终在再次添加之前检查该行是否存在,因为您知道该问题可能首先存在。

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

+0

“投掷异常很贵”,是否比检查记录每次都不存在更昂贵?重复呼叫的次数可能少于2%。 – 2009-08-24 07:52:47

+0

直到您有确凿的证据证明首先检查数据库实际上导致该领域的问题时,我才会担心性能 - 直到此时,您在这方面做的任何事情都是不成熟的优化。首先检查是遵循的最佳模式,因为代码的意图是清晰的,而且您不忽略忽略异常的信息。 – Sam 2009-08-24 23:57:15

1

虽然不太可能,不检查,然后插入一条记录的竞争条件?如果是这样,你应该为它进行防守编程,这意味着捕捉和检查任何异常情况。

在这种情况下,您应该在选择忽略它之前检查异常的类型和/或它的基础错误编号。通过这种方式,您可以忽略与试图插入重复记录相关的异常(可能是主键约束冲突)。你会想要以不同的方式处理其他类型的异常。