列上自动增量的 h2 数据库问题会产生间隙

h2 database problem with autoincrement on column generates gap

当我第一次启动 h2 数据库并进行一些插入时,自动生成的 ID 正确地显示为 1、2、3 等等,但是当我停止 springboot 应用程序并将其打开时然后它又从上面的 30 个位置开始,这个 post 遇到的问题基本上完全相同 In H2 database, the auto_increment field is incremented by 32?

我可以通过在 h2 控制台执行“shutdown”命令来避免这个问题,然后关闭我的 springboot 应用程序,但问题是我希望这个问题得到解决通过 java 代码以一种更优雅的方式,这样你就不必去 h2console 自己做,在生产中也不会很好。

仅当您将 h2 数据库保存在文件中时才会出现此问题,如果您在每次应用程序启动时创建一个新数据库,那么这应该无关紧要。有谁知道如何解决这个问题?

我已经在 spring 属性上尝试了一些配置但没有成功,我正在考虑的一个解决方案是制作一个 @PreDestroy 方法,该方法将在 spring 之前执行关闭语句关闭(顺便说一句,通过 eclipse ide),但我不确定这是否有效,或者它是否是正确的解决方案,我 post 对此表示希望有人最近遇到了这个问题并且知道该怎么做因为其他 post 类似的人不提供ide 解决方案,只是解释导致问题的原因

我的应用程序属性:

spring.datasource.url=jdbc:h2:./src/main/resources/data;DB_CLOSE_ON_EXIT=FALSE;AUTO_RECONNECT=TRUE
spring.jpa.hibernate.ddl-auto=update
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
spring.h2.console.settings.trace=false
spring.h2.console.settings.web-allow-others=false

其他 post 有此问题:

In H2 database, the auto_increment field is incremented by 32?

更新:

像在这个 gu 上一样使用执行器端点关闭时ide https://www.baeldung.com/spring-boot-shutdown 该错误没有发生,我想这是因为它以“好的方式”关闭了应用程序,但问题是我也不认为解决方案是调用端点来关闭应用程序,必须有一个在 Eclipse 中使用终止按钮的方法,并且不会发生此错误 =(

您可以使用 NO CACHE 子句禁用标识列生成器的缓存:

CREATE TABLE TEST(
    ID BIGINT GENERATED BY DEFAULT AS IDENTITY(NO CACHE) PRIMARY KEY,
    V INTEGER
);

如果你使用sequence而不是identity column,你需要用同样的方法禁用它的缓存:

CREATE SEQUENCE TEST_SEQUENCE NO CACHE;

它略微增加了磁盘I/O,但是。您还应该了解,如果应用程序可以插入一行并在之后回滚事务,则仍然可能存在间隙,生成的值不会被重用。

实际上,以硬方式中止具有嵌入式数据库的应用程序是一个非常糟糕的主意,因为它可能会导致数据丢失或数据库损坏。如果您使用 DB_CLOSE_ON_EXIT=FALSE,您必须始终在终止您的应用程序或关闭所有连接之前执行 SHUTDOWN 命令(这仅在未使用 DB_CLOSE_DELAY 时才足够)。

如果你没有理由使用DB_CLOSE_ON_EXIT=FALSE(只有当应用程序注册一个关闭钩子并在JVM关闭期间与数据库一起工作时才需要),最好删除这个连接选项.

正确关闭序列生成器的数据库缓存不会影响生成的值。

注意: 请记住,当使用 @GeneratedValue(strategy = GenerationType.IDENTITY) 时,H2 会在首次启动时生成随机序列名称,您可以在 h2console 上查看,只需使用 ALTER SEQUENCE paste_seq_name NO CACHE

示例: ALTER SEQUENCE SYSTEM_SEQUENCE_63AF2D03_F992_40AD_88AA_6E0F10DA12CE NO CACHE