【发布时间】:2020-11-30 12:32:45
【问题描述】:
我最近才发现在 Spring Boot JPA 2.2.6 和 Mysql 8 中批量插入。
要使批量插入工作,我必须更改以下内容:
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", unique = true, nullable = false)
private long id;
到:
@Id
@GeneratedValue(generator = "generator")
@GenericGenerator(name = "generator", strategy = "increment")
@Column(name = "id", unique = true, nullable = false)
private long id;
带有一些附加属性:
spring:
jpa:
properties:
hibernate:
generate_statistics: true
jdbc:
batch_size: 1000
order_inserts: true
order_updates: true
当我使用单个服务器实例进行测试时,批量插入似乎正在工作。但我刚刚注意到,当有两个 API 实例时,id 递增无法正常工作。
似乎正在发生的事情是:
- POST 创建实体并将其持久保存在 MySQL 数据库中。请求由实例 1 接收。实体获取 id 1。
- POST 创建实体并将其持久保存在 MySQL 数据库中。请求被实例 2(Round Robin 请求路由)接收。抛出以下异常:
Aug 10 20:47:00 ip-10-1-0-120.dev.dev.uk bash[25107]: 2020-08-10 20:47:00.408 INFO 25107 --- [nio-8080-exec-4] o.h.e.j.b.internal.AbstractBatchImpl : HHH000010: On release of batch it still contained JDBC statements
Aug 10 20:47:00 ip-10-1-0-120.dev.dev.uk bash[25107]: 2020-08-10 20:47:00.410 ERROR 25107 --- [nio-8080-exec-4] o.h.e.jdbc.batch.internal.BatchingBatch : HHH000315: Exception executing batch [java.sql.BatchUpdateException: Duplicate entry '1' for key 'PRIMARY'], SQL: insert into REMINDER (deleted, created, created_by, last_modified, last_modified_by, context, notification_type, reminder_date, user_id, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Aug 10 20:47:00 ip-10-1-0-120.dev.dev.uk bash[25107]: 2020-08-10 20:47:00.411 WARN 25107 --- [nio-8080-exec-4] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1062, SQLState: 23000
Aug 10 20:47:00 ip-10-1-0-120.dev.dev.uk bash[25107]: 2020-08-10 20:47:00.412 ERROR 25107 --- [nio-8080-exec-4] o.h.engine.jdbc.spi.SqlExceptionHelper : Duplicate entry '1' for key 'PRIMARY'
当我想使用批量插入时,如何防止在使用多个实例时引发重复键异常,同时确保每个新实体始终在多个实例中获取下一个可用的递增 id?
【问题讨论】:
-
您必须将其从
long更改为Long因为原语不能为空,但Long可以。将您的 id 设置为 null,只要您在数据库中正确设置它以增加 id,spring 将自动为其获取下一个 id。
标签: java mysql spring spring-boot jpa