java - 为什么 Hibernate 在使用 IDENTITY 标识符生成器时禁用 INSERT 批处理

标签 java spring hibernate jpa transactions

Hibernate 文档说:

Hibernate disables insert batching at the JDBC level transparently if you use an identity identifier generator.

但是我所有的实体都有这个配置:

@Id
@GeneratedValue(strategy = javax.persistence.GenerationType.IDENTITY)
private Integer id;

当我在 So 上面使用这个身份时

  1. IDENTITY 有什么问题?
  2. 是否禁用了批量插入?
  3. 我该如何解决这个问题?

最佳答案

事务性后写

Hibernate 尝试将持久性上下文刷新延迟到最后可能的时刻。这种策略传统上被称为事务性后写。

write-behind 与 Hibernate 刷新有关,而不是任何逻辑或物理事务。在事务期间,刷新可能会发生多次。

刷新的更改仅对当前数据库事务可见。在提交当前事务之前,其他并发事务看不到任何更改。

身份

IDENTITY 生成器允许 intbigint 列按需自动递增。递增过程发生在当前正在运行的事务之外,因此回滚可能最终会丢弃已分配的值(可能发生值间隙)。

增量过程非常有效,因为它使用数据库内部的轻量级锁定机制,而不是更重量级的事务性进程锁。

唯一的缺点是在执行 INSERT 语句之前我们无法知道新分配的值。这种限制阻碍了 Hibernate 采用的事务性后写刷新策略。出于这个原因,Hibernates 使用 IDENTITY 生成器禁用了对实体的 JDBC 批处理支持。

表格

唯一的解决方案是使用由 pooled-lo 支持的 TABLE 标识符生成器。优化器。此生成器也适用于 MySQL,因此它克服了缺乏数据库 SEQUENCE 支持的问题。

但是,TABLE生成器的性能比 IDENTITY 差,所以最后,这不是一个可行的替代方案。

结论

因此,在 MySQL 上使用 IDENTITY 仍然是最好的选择,如果需要批量插入,可以使用 JDBC。

关于java - 为什么 Hibernate 在使用 IDENTITY 标识符生成器时禁用 INSERT 批处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27697810/

相关文章:

java - 在 Java 中检查某个应用程序是否处于焦点

java - 无法使用 ServletFileUpload 上传 100MB 文件

java - JPA/Hibernate 选择查询返回重复记录

Java 棋盘图像未显示

java - 如何克服java堆空间的OutOfMemoryError?

java - 如何模拟ad hoc网络节点?

java - 使用@Transient注解进行持久化存储

java - Spring Boot 项目作为可执行 jar 运行时找不到 Hibernate.cfg.xml

java - Hibernatemock 的文档或教程?

java - 如何在 Hibernate 中仅检索部分(少数)pojo 字段?