Java + MySQL完整性违规处理

我使用JDBC(mysql数据库)编写Java程序。 当我违反mysql完整性时(我尝试插入相同的主键值)我捕获SQLexception。 我应该以它的方式编写它可能永远不会发生(首先布尔函数检查主键值是否已经在DB中然后调用插入),或者是否可以通过exception处理它? 示例:

catch (SQLException ex) {ex.printStackTrace(); showSomeErrorDialog(); } 

确实有两种方法可以达到这个目的:

  1. 在插入之前测试记录是否存在 – 在同一事务中。

  2. 确定SQLException#getSQLState()是否以23开头,这是违反SQL规范的约束。 它可能是由比“仅仅”约束违规更多的因素引起的。 您不应将每个SQLException修改为约束违规。

     public static boolean isConstraintViolation(SQLException e) { return e.getSQLState().startsWith("23"); } 

我会选择第一个,因为它在语义上更正确。 事实上这不是特殊情况。 你知道它可能会发生。 但是,在交互不同步(无意识或优化性能)的繁重并发环境中,它可能会失败。 然后,您可能希望确定exception。

也就是说,通常不应该在主键上出现约束违规。 在设计良好的数据模型中,它使用技术密钥作为主键,它们通常由数据库本身管理。 这个领域不应该是一个独特的关键吗?

有两种可能的答案:

  • 如果您知道应用程序旨在避免此类行为,请使用该exception
  • 如果您的应用程序经常出现这些错误,请使用测试。

正如其他人提到的那样,有两种可能的方法,一种是测试然后插入/更新否则处理SQLexception。 这两种方法都有其缺点:

  • 警告“插入前测试”是每个事务都会有其他查询,这将影响性能。 当这种错误的交易数量很少时,这尤其是一个更大的问题。
  • “评估SQLexception”的警告是,此类exception消息是特定于数据库的。 在大多数情况下,这些消息除了声明存在约束违规外,不会提供具体信息。

所以,我将提出一种两者混合的方法。

  • 插入前不要进行测试。
  • 让数据库抛出exception。
  • 捕获SQLexception。
  • 在exception流程(catch块)中,执行其他查询以形成非常特定的错误消息,以指示客户确实失败的内容(唯一键,主键,外键,特定列等)。

这可能需要额外的代码行,但它肯定会提高性能并生成友好的错误消息。