使用 Hibernate 防止违反 UNIQUE 约束
Prevent violating of UNIQUE constraint with Hibernate
我有一个像 (id INTEGER, sometext VARCHAR(255), ....)
这样的 table,其中 id
作为主键,sometext
上有一个 UNIQUE 约束。它用于 Web 服务器,请求需要找到对应于给定 sometext
的 id
(如果存在),否则将插入新行。
这是对此 table 的唯一操作。 table 没有更新,也没有其他操作。它的唯一目的是持久地遇到 sometext
个值。这意味着我不能删除 id
并使用 sometext
作为主键。
我执行以下操作:
- 首先,我查询自己的缓存以避免任何数据库访问。几乎总是这样,我就完成了。
- 否则,我使用 Hibernate Criteria 按
sometext
查找行。通常,这会再次起作用,我就完成了。
- 否则,我需要插入一个新行。
这工作正常,除非有两个重叠的请求具有相同的 sometext
。然后 ConstraintViolationException
结果。我需要 INSERT IGNORE
或 INSERT ... ON DUPLICATE KEY UPDATE
(Mysql 语法)或 MERGE(Firebird 语法)之类的东西。
我想知道有哪些选择?
AFAIK Hibernate merge
仅适用于 PK,因此不合适。我想,本机查询可能有帮助也可能没有帮助,因为在第二次 INSERT 发生时它可能会或可能不会提交。
让数据库处理并发。纯粹为了插入新行而启动一个辅助事务。如果它因 ConstraintViolationException 而失败,只需回滚该事务并读取新行。
如果重复的可能性很高,不确定这是否能很好地扩展,如果一定百分比(取决于数据库)的事务必须使插入失败然后重新选择,则需要大量额外的工作。
辅助事务将事务添加新文本所需的时间减到最少,假设数据库正确支持它,线程 1 事务可能会导致线程 2 select/insert 挂起直到线程 1 事务被提交或回滚。整体数据库设计也可能影响事务吞吐量。
我不一定质疑为什么sometext不能成为PK,想知道为什么你需要把它分解出来。当然,如果某些文本记录很大,大容量可能会大大节省 space,这几乎就像您在尝试模拟 lucene 索引来为您提供完整的文本值列表。
我有一个像 (id INTEGER, sometext VARCHAR(255), ....)
这样的 table,其中 id
作为主键,sometext
上有一个 UNIQUE 约束。它用于 Web 服务器,请求需要找到对应于给定 sometext
的 id
(如果存在),否则将插入新行。
这是对此 table 的唯一操作。 table 没有更新,也没有其他操作。它的唯一目的是持久地遇到 sometext
个值。这意味着我不能删除 id
并使用 sometext
作为主键。
我执行以下操作:
- 首先,我查询自己的缓存以避免任何数据库访问。几乎总是这样,我就完成了。
- 否则,我使用 Hibernate Criteria 按
sometext
查找行。通常,这会再次起作用,我就完成了。 - 否则,我需要插入一个新行。
这工作正常,除非有两个重叠的请求具有相同的 sometext
。然后 ConstraintViolationException
结果。我需要 INSERT IGNORE
或 INSERT ... ON DUPLICATE KEY UPDATE
(Mysql 语法)或 MERGE(Firebird 语法)之类的东西。
我想知道有哪些选择?
AFAIK Hibernate merge
仅适用于 PK,因此不合适。我想,本机查询可能有帮助也可能没有帮助,因为在第二次 INSERT 发生时它可能会或可能不会提交。
让数据库处理并发。纯粹为了插入新行而启动一个辅助事务。如果它因 ConstraintViolationException 而失败,只需回滚该事务并读取新行。
如果重复的可能性很高,不确定这是否能很好地扩展,如果一定百分比(取决于数据库)的事务必须使插入失败然后重新选择,则需要大量额外的工作。
辅助事务将事务添加新文本所需的时间减到最少,假设数据库正确支持它,线程 1 事务可能会导致线程 2 select/insert 挂起直到线程 1 事务被提交或回滚。整体数据库设计也可能影响事务吞吐量。
我不一定质疑为什么sometext不能成为PK,想知道为什么你需要把它分解出来。当然,如果某些文本记录很大,大容量可能会大大节省 space,这几乎就像您在尝试模拟 lucene 索引来为您提供完整的文本值列表。