Hibernate + 并发插入 (MySQL INSERT IGNORE)
Posted
技术标签:
【中文标题】Hibernate + 并发插入 (MySQL INSERT IGNORE)【英文标题】:Hibernate + concurrent inserts (MySQL INSERT IGNORE) 【发布时间】:2011-06-05 17:12:58 【问题描述】:我正在学习使用 Hibernate。我想知道如何正确地在休眠中进行并发插入。
我有一个 url 表定义为:
CREATE TABLE `urls` (
id INT PRIMARY KEY AUTO_INCREMENT,
md5 CHAR(32) UNIQUE,
url TEXT
);
该表的目的是维护一个映射id url。 md5 字段是来自 url 的 md5 和,一般一个 url 可以长于 1024 字节,这是 mysql 中 UNIQUE 约束的限制。
我的问题是关于 url -> id 函数处理并发的查询。在 JDBC 实现中,我执行以下步骤:
-
选择 id WHERE md5=md5(url);
如果存在,返回id,否则:
INSERT IGNORE INTO url (md5,url) VALUES (MD5(url), url);
重试步骤 1。
即使在第 2 步和第 3 步之间插入了请求的 url,它也能正常工作。如何使用 Hibernate 执行此操作?
【问题讨论】:
【参考方案1】:您可以使用注释@SQLInsert。它允许您指定在插入期间要使用的 SQL 语句。问题是:Hibernate 不仅仅是从数据库中插入/更新/选择数据。也就是说,我很确定仅使用 @SQLInsert 一开始可能会起作用,但是我不确定当您遇到您描述的场景(步骤 2 和步骤 3 之间的并发插入)时 Hibernate 会如何表现,特别是因为它不执行第 4 步。相反,它调用 JDBC 的“getGeneratedKeys”来检索生成的 ID(我怀疑,如果插入被忽略,则该 ID 将为空)。
简而言之:我看到的唯一解决方案是使用@SQLInsert,但您会想要使用它并确保 Hibernate 在并发插入发生时行为正确。
【讨论】:
以上是关于Hibernate + 并发插入 (MySQL INSERT IGNORE)的主要内容,如果未能解决你的问题,请参考以下文章
如何在 MySQL 上使用 Hibernate 批量插入递增的 ID?
MYSQL 和 Hibernate:插入默认值 0 而不是“null”
错误 [TRACE] [rpctest] - 查找入口点类:使用 GWT 使用 Hibernate 将数据插入 MySql