java Spring Boot JPA是否可以使用IDENTITY generator或等效程序进行批插入?
我最近发现了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接收(循环请求路由)。将引发以下异常:
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
# 1 楼答案
GenerationType.IDENTITY
不允许批量插入。例如,您可以看到here事实上,当使用多个实例时,此代码将不起作用。因为策略
increment
使用IncrementGenerator
实现。在这里,您可以看到缓存了数据库中的最大ID值。因此,如果应用程序的另一个实例插入了一个值,那么当前实例将永远不会知道该值要解决您的问题,您可以使用
或者您应该将数据库更改为PostgreSQL,然后必须使用
sequence
策略如果这些选项不适合您,您可以在
DefaultIdentifierGeneratorFactory
中看到生成标识符的其他策略的实现