개발

H2 설정 충돌 AUTO_SERVER vs DB_CLOSE_ON_EXIT

ikkison 2026. 2. 19. 12:16

local, dev 환경에서 H2 를 사용하는 경우 아래와 같은 에러가 발생하는 경우가 있다.

 

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.exception.GenericJDBCException: Unable to open JDBC Connection for DDL execution [Feature not supported: "AUTO_SERVER=TRUE && DB_CLOSE_ON_EXIT=FALSE" [50100-232]] [n/a]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1826) ~[spring-beans-6.2.15.jar:6.2.15]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:607) ~[spring-beans-6.2.15.jar:6.2.15]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:529) ~[spring-beans-6.2.15.jar:6.2.15]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:339) ~[spring-beans-6.2.15.jar:6.2.15]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:373) ~[spring-beans-6.2.15.jar:6.2.15]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:337) ~[spring-beans-6.2.15.jar:6.2.15]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:207) ~[spring-beans-6.2.15.jar:6.2.15]

 

에러 메시지의 핵심은 이 문장이다.

 

Feature not supported: "AUTO_SERVER=TRUE && DB_CLOSE_ON_EXIT=FALSE" [50100-232]

 

이는 H2 최신 버전에서 AUTO_SERVER=TRUE 옵션과 DB_CLOSE_ON_EXIT=FALSE 옵션을 동시에 사용하는 것을 지원하지 않기 때문에 충돌이 발생하였다.

 

각 설정에 입각하여 충돌원인을 파악하고 방안을 고안해보자.

 


AUTO_SERVER=TRUE

  • 이 옵션은 파일 기반의 H2 DB를 사용함에도 내부적으로 임시 네트워크 서버를 띄운다.
  • springboot등 어플리케이션이 DB파일을 점유하고 있을 때, DBClient 나 H2콘솔 등을 사용하여 동시 접속을 시도하면 파일이 Lock이 걸리게 된다.
  • 그래서 AUTO_SERVER=TRUE 옵션을 설정하여 첫번째로 접속한 프로세스가 서버 역할을 수행하게하여 다른 프로세스들이 그 서버를 통해서 파일에 접근할 수 있도록 한다.
  • H2가 스스로 접속 제어권을 갖게 된다.

DB_CLOSE_ON_EXIT=FALSE

  • JVM이 종료될 때 H2 DB가 자동을 닫히는 기능을 비활성화한다.
  • H2를 인메모리 방식으로 사용하는 경우 JVM 종료 직전까지 DB 작업을 보장하는 경우 사용한다.
  • 그러나 이 설정을 사용하면 DB 커넥션이 명시적으로 닫히지 않고 남아있어 위험할 수 있다.

 


충돌 원인

두 옵션이 충돌하는 지점은 "누가 DB를 닫을 것인가?" 에 대해 주도권 때문이다.

 

1. 관리주체의 혼선

  • AUTO_SERVER 모드에서는 H2가 스스로 서버 역할을 하면서 클라이언트들이 다 나갔는지 확인 후 안전하게 close 한다.
  • DB_CLOSE_EXIT=FALSE 인 경우는 JVM 이 꺼져도 닫지말라고 명령을 한다.

AUTO_SERVER

" 클라이언트들 확인 후 안전하게 닫아!!!"

VS
DB_CLOSE_EXIT=FALSE

"JVM이 꺼져도 닫지마!!!"

 

2. 파일 Lock 위험

  • AUTO_SERVER 모드에서 강제로 DB를 닫지 않고 JVM만 꺼져버리면, DB 파일(.lock 파일 등)이 제대로 정리되지 않는다.
  • 그래서 다음번 실행 때 "데이터베이스가 이미 사용 중입니다" 라는 에러를 만날 확률이 매우 높아진다.

 

3. H2 2.x 정책

  • 이전 1.x 버전에서는 경고만 하였다.
  • 최신 버전에서는 데이터 무결성을 위해 이 두 설정조합을 "지원하지 않는 기능 / Feature not supported" 로 차단하였다.

나의 local, dev profile 에서는 아래와 같이 사용한다.

url: jdbc:h2:file:./data/testdb;AUTO_SERVER=TRUE;DB_CLOSE_DELAY=-1