【发布时间】:2013-08-16 05:59:37
【问题描述】:
我在 MySQL 数据库服务器上使用休眠。考虑一个示例数据库表:
create table User (
USER_ID int not null auto_increment primary key,
USERNAME varchar(50) not null unique,
PASSWORD varchar(50) not null
)
使用此表结构,如果尝试存储更长或重复的用户名,则会抛出 org.hibernate.exception.DataException 和 org.hibernate.exception.ConstraintViolationException .
问题:在这种情况下哪种方法更好:
- 在传递值之前检查数据库约束(防止出现预期异常)。
- 稍后传递未经检查的数据并捕获数据库异常(DataException 和 ConstraintViolationException)。
由于检查名称长度是一个常数时间操作,我更喜欢手动检查它,但这个问题对我来说很重要,因为手动确保用户名的唯一性需要我迭代一长串现有用户。
请建议哪种方法更值得推荐。感谢回复!
【问题讨论】:
-
预先检查很昂贵(额外查询)并且不可靠(在您检查后,另一个进程可能会添加用户)。编写昂贵的不可靠代码没有多大意义。
-
请注意,在进程#1 和#2 之间,其他用户可以插入相同的用户名。在某些情况下,检查 #1 可能没有用。但是现在有了强大的 UI,我经常在编写表单时看到错误消息更新。 (例如:写入用户名但未提交后,UI 会告诉我该名称是否被占用)。
-
所以我可以得出结论,应该手动实现线程安全检查(如检查用户名长度),并捕获 DB 服务器抛出的异常,而确切的结果可能取决于并行线程。?