Java + MySQL 完整性违规处理
我使用 JDBC(mysql 数据库)编写 Java 程序。 当我违反 mysql 完整性时(如果我尝试插入相同的主键值),我会捕获 SQL 异常。 我应该以永远不会发生的方式编写它(首先布尔函数检查主键值是否不在数据库中,然后调用插入),或者可以仅通过异常来处理它吗? 例子 :
catch (SQLException ex) {ex.printStackTrace(); showSomeErrorDialog(); }
I write Java program using JDBC (mysql database).
When I violate mysql integrity (f.e. I try to insert same primary key value) I catch SQL exception.
Should I write it in way it may never happen (f.e. at first boolean function checking whether primary key value isn't already in DB and then calling insert), or is it okay to handle it just by exception?
Example :
catch (SQLException ex) {ex.printStackTrace(); showSomeErrorDialog(); }
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
实际上,基本上有两种方法可以实现此目的:
在插入之前测试记录是否存在 - 在同一事务内。
确定是否<捕获的
SQLException
的 code>SQLException#getSQLState() 以23
开头,这是根据 SQL 规范。也就是说,它可能是由更多因素引起的,而不仅仅是“仅仅”违反约束。您不应将每个SQLException
修改为违反约束。我会选择第一个,因为它在语义上更正确。事实上,这并非特例。也就是说,您知道这可能会发生。但在事务未同步(无意中或为了优化性能)的高并发环境中,它可能会失败。然后您可能想要确定异常。
也就是说,您通常不应该在主键上遇到约束违规。在使用技术键作为主键的精心设计的数据模型中,它们通常由数据库本身管理。该字段不应该是唯一键吗?
There are indeed basically two ways to achieve this:
Test if record exists before inserting --inside the same transaction.
Determine if
SQLException#getSQLState()
of the catchedSQLException
starts with23
which is a constraint violation as per the SQL specification. It can namely be caused by more factors than "just" a constraint violation. You should not amend everySQLException
as a constraint violation.I would opt for the first one as it is semantically more correct. It is in fact not an exceptional circumstance. You namely know that it is potentially going to happen. But it may potentially fail in heavy concurrent environment where transactions are not synchronized (either unawarely or to optimize performance). You may then want to determine the exception instead.
That said, you normally shouldn't get a constraint violation on a primary key. In well designed datamodels which uses technical keys as primary keys they are normally to be managed by the database itself. Isn't the field supposed to be an unique key?
有两种可能的答案:
There are two possible answers :
正如其他人提到的,有两种可能的方法,一种是测试然后插入/更新,否则处理 SQL 异常。这两种方法都有其缺点:
事务将有额外的查询,这会影响性能。当此类错误交易数量很少时,这尤其是一个更大的问题。
异常消息是非常特定于数据库的。大多数时候,这些消息并不
除了说明存在违反约束之外,还提供具体信息。
因此,我将提出一种两者混合的方法。
例外。
块),执行额外的查询以形成非常具体的错误消息
向客户指示到底发生了什么故障(唯一键、主键、
外键、特定列等)。
这可能需要几行额外的代码,但它肯定会提高性能并生成友好的错误消息。
As others have mentioned that there are two possible approaches, one is to test and then insert/update otherwise handle SQL Exception. Both these approaches have their downsides:
transaction will have additional queries which will impact performance. This is specially a bigger issue when such erroneous transactions are few in number.
exception messages are very database specific. These messages, most of the time, don't
give specific information beyond stating that there is constrain violation.
So, I will propose an approach which is hybrid of the two.
exception.
block), do additional queries to form very specific error messages to
indicate customers what has exactly failed (unique key, primary key,
foreign key, specific columns etc).
This may require few additional lines of code but it definitely improves performance and generates friendly error messages.