列上自动增量的 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
当我第一次启动 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