【问题标题】:Why does Hibernate disable INSERT batching when using an IDENTITY identifier generator为什么 Hibernate 在使用 IDENTITY 标识符生成器时禁用 INSERT 批处理
【发布时间】:2015-02-26 04:00:39
【问题描述】:

Hibernate 文档说:

Hibernate 在 JDBC 级别透明地禁用插入批处理,如果 您使用身份标识符生成器。

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

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

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

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

【问题讨论】:

    标签: java spring hibernate jpa transactions


    【解决方案1】:

    事务性后写

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

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

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

    身份

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

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

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

    表格

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

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

    结论

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

    【讨论】:

    • 感谢弗拉德的帮助,我现在明白了所有这些是如何工作的;)
    • @Vlad,使用IDENTITY 生成器似乎很清楚INSERTS 不能被批处理,但是UPDATES 呢,可以使用IDENTITY 生成器和mysql 对它们进行批处理?当然,在设置正确的配置参数之后。 (hibernate.jdbc.batch_sizehibernate.order_updateshibernate.jdbc.batch_versioned_data)。我试过了,但它不起作用。附:我没有使用JOOQ
    • 正如我在 my book 中解释的那样,UPDATE 和 DELETE 语句是受支持的,因此要么是配置问题,要么是您没有正确记录语句。
    • 应该没问题吧。当您将一批参数值发送到单个 PreparedStatement 时,您必须检查 MySQL 日志记录的工作原理
    • 只有批处理 INSERT 受到影响。 UPDATE 和 DELETE 语句可以使用 IDENTITY 很好地批处理。
    猜你喜欢
    • 2013-07-20
    • 2011-09-01
    • 2010-12-16
    • 2018-05-27
    • 1970-01-01
    • 1970-01-01
    • 2011-02-09
    • 2020-04-03
    • 1970-01-01
    相关资源
    最近更新 更多