Java + MySQL完整性违规处理
我使用JDBC(mysql数据库)编写Java程序。 当我违反mysql完整性时(我尝试插入相同的主键值)我捕获SQLexception。 我应该以它的方式编写它可能永远不会发生(首先布尔函数检查主键值是否已经在DB中然后调用插入),或者是否可以通过exception处理它? 示例:
catch (SQLException ex) {ex.printStackTrace(); showSomeErrorDialog(); }
确实有两种方法可以达到这个目的:
-
在插入之前测试记录是否存在 – 在同一事务中。
-
确定
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块)中,执行其他查询以形成非常特定的错误消息,以指示客户确实失败的内容(唯一键,主键,外键,特定列等)。
这可能需要额外的代码行,但它肯定会提高性能并生成友好的错误消息。