일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- No tests found for given includes
- java version
- AWS CLI
- LeetCode
- Medium
- java 11
- xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools)
- java 1.8 11
- error
- log error
- springboot
- parse
- ssl프로토콜확인
- xcrun: error: invalid active developer path
- java
- mac os git error
- mysql executequery error
- java 버전 변경
- statement.executequery() cannot issue statements that do not produce result sets.
- java 여러개 버전
- springboottest
- OpenFeign
- ssl이란?
- aws
- easy
- yum install java
- JUnit
- tls프로토콜확인
- Java 1.8
- 스프링부트테스트
- Today
- Total
쩨이엠 개발 블로그
[ H2 ] Unsupported connection setting "MVCC" 본문
H2 커넥션 도중 에러가 났다
Error 내용
com.example.demo.MemberRepositoryTest > testMember() FAILED
org.springframework.dao.InvalidDataAccessApiUsageException at MemberRepositoryTest.java:23
Caused by: javax.persistence.TransactionRequiredException at MemberRepositoryTest.java:23
2020-11-08 15:45:22.099 ERROR 38542 --- [ task-1] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Exception during pool initialization.
org.h2.jdbc.JdbcSQLNonTransientConnectionException: Unsupported connection setting "MVCC" [90113-200]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:622) ~[h2-1.4.200.jar:1.4.200]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:429) ~[h2-1.4.200.jar:1.4.200]
at org.h2.message.DbException.get(DbException.java:205) ~[h2-1.4.200.jar:1.4.200]
at org.h2.message.DbException.get(DbException.java:181) ~[h2-1.4.200.jar:1.4.200]
at org.h2.engine.ConnectionInfo.readSettingsFromURL(ConnectionInfo.java:269) ~[h2-1.4.200.jar:1.4.200]
at org.h2.engine.ConnectionInfo.<init>(ConnectionInfo.java:78) ~[h2-1.4.200.jar:1.4.200]
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:152) ~[h2-1.4.200.jar:1.4.200]
at org.h2.Driver.connect(Driver.java:69) ~[h2-1.4.200.jar:1.4.200]
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) ~[HikariCP-3.4.5.jar:na]
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:358) ~[HikariCP-3.4.5.jar:na]
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:206) ~[HikariCP-3.4.5.jar:na]
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:477) ~[HikariCP-3.4.5.jar:na]
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:560) ~[HikariCP-3.4.5.jar:na]
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115) ~[HikariCP-3.4.5.jar:na]
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) ~[HikariCP-3.4.5.jar:na]
at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:180) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:68) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:101) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:237) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.injectServices(DefaultIdentifierGeneratorFactory.java:152) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.injectDependencies(AbstractServiceRegistryImpl.java:286) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:243) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.<init>(InFlightMetadataCollectorImpl.java:176) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:118) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1224) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1255) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58) ~[spring-orm-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:391) ~[spring-orm-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]
2020-11-08 15:45:22.100 WARN 38542 --- [ task-1] o.h.e.j.e.i.JdbcEnvironmentInitiator : HHH000342: Could not obtain connection to query metadata : Unsupported connection setting "MVCC" [90113-200]
2020-11-08 15:45:22.101 WARN 38542 --- [extShutdownHook] o.s.b.f.support.DisposableBeanAdapter : Invocation of destroy method failed on bean with name 'entityManagerFactory': org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
2020-11-08 15:45:22.101 INFO 38542 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'
Setting
- Spring boot 2.3.4.RELEASE
- H2 1.4.200
application.yml
spring:
datasource:
url: jdbc:h2:tcp://localhost/~/jpa;MVCC=TRUE
username: sa
password:
driver-class-name: org.h2.Driver
에러 내용은 MVCC가 커넥션 세팅이 지원되지 않는다는건데
h2 버전이 1.4.200인 경우 MVCC=TRUE가 있으면 DB연결에 실패한다고한다
빼고나니 바로 접속이 잘 된다
근데 MVCC가 뭔데? 해서 찾아보았다
MVCC란?
: 다중 버전 동시성 제어 (Multi-Version Concurrency Control)
: 동시성을 제어하기 위해 사용하는 매커니즘 중 하나
.. 뭔소린지 모르겠다
그래서 동시성이란?
말그대로 동시에 데이터베이스에 접근이 가능하도록 하는 것인데 이는 일관성과 반비례관계를 가지고 있다
동시에 접속하는 사람이 많으면 데이터가 일관적이지 않을 수 있고,
일관적인 데이터를 위해서는 동시 접속하는 동시성을 낮출 수 밖에 없다
하여 동시성 제어의 목표는 동시에 실행되는 트랜잭션을 최대화하면서도, 데이터 무결성이 유지되도록 하는 것이다.
읽기와 쓰기 작업이 서로를 방해해 동시성을 떨어뜨리고, 공유 Lock을 사용함에도 데이터 일관성이 훼손될 수 있는 문제를 해결하기 위해 MVCC 매커니즘을 사용한다
MVCC 매커니즘 동작 프로세스
- 데이터를 변경 할 때 그 변경사항을 Undo 영역에 저장한다
- 데이터를 읽다가 트랜잭션 시작 시점 이후에 변경된 값을 발견하면 Undo 영역에 저장된 정보를 이용해 버전을 생성하고 그것을 읽는다
장점
- 잠금을 기다릴 필요가 없기 때문에 일반적인 RDBMS보다 매우 빠르다 (동시성)
- 데이터를 읽을 때 다른 사용자의 CRUD에 영향을 받지 않는다 (일관성)
단점
- 데이터의 버전 충돌이 있을 수 있다 -> 애플리케이션 영역에서 문제를 해결해야함
- 사용하지 않는 버전들에 대한 정리가 필요하다
Snapshot too old
MVCC 매커니즘은 Undo 영역을 활용함으로써 동시성과 일관성을 유지할 수 있는 대신, Snapshot too old 에러가 발생한다
이 에러는 Undo 영역에 저장된 정보가 다른 트랜잭션에 의해 재사용돼 필요한 버전을 생성할 수 없을 때 발생한다.
쉽게말하면 Undo 데이터가 덮어씌워져서 발생한 에러이다.
대신 발생가능성을 줄이는 방법이 있다
- Undo 영역의 크기를 증가시킨다(쿼리를 실행하는 동안 덮여쓰여질 크기보다 크게 혹은 추가하는게 좋으나 수동보다는 자동으로 관리하는것을 권장)
- 커밋 수를 줄인다 (불필요한 커밋 제거)
- 트랜잭션이 몰리지 않도록 시간이 오래걸리는 쿼리는 튜닝 혹은 힌트 추가로 시간을 단축시키거나 단계적으로 실행할 수 있도록 쿼리를 조정한다
- order by등의 sort 연산이 발생하도록 한다