Repository: h2database/h2database

Issue #1841: Deadlock during concurrent shutdown attempts with 1.4.199
Created: 2019-04-09T14:20:19Z
Description
With the upgrade to H2 1.4.199 we seem to be getting deadlocks during shutdown. Rollback to 1.4.197 does not appear to exhibit the same problem.
Environment
JDK 11
H2 1.4.199, default Spring Boot Devtools configuration
Spring Framework 5.1.6
Spring Boot 2.1.4
Hikari Pool 3.2.0, default Spring Boot configuration
Background
We use H2 as the backing test database for Spring Boot tests. We have several integration tests in different classes using @SpringBootTest, each of which appear to trigger a destroy when all tests finish and application contexts are closed. On 1.4.199 these shutdown triggers appear to deadlock due to different sessions being acquired and locked during the SHUTDOWN command.
This doesn't appear to happen on 1.4.197.
Java stack information for the threads listed above:
===================================================
"Thread-31":
	at org.h2.command.dml.TransactionCommand.update(TransactionCommand.java:97)
	- waiting to lock <0x00000000ecc99788> (a org.h2.engine.Session)
	at org.h2.command.CommandContainer.update(CommandContainer.java:133)
	at org.h2.command.Command.executeUpdate(Command.java:267)
	- locked <0x00000000eccfcb48> (a org.h2.engine.Session)
	at org.h2.jdbc.JdbcStatement.executeInternal(JdbcStatement.java:233)
	- locked <0x00000000eccfcb48> (a org.h2.engine.Session)
	at org.h2.jdbc.JdbcStatement.execute(JdbcStatement.java:205)
	at com.zaxxer.hikari.pool.ProxyStatement.execute(ProxyStatement.java:95)
	at com.zaxxer.hikari.pool.HikariProxyStatement.execute(HikariProxyStatement.java)
	at org.springframework.boot.devtools.autoconfigure.DevToolsDataSourceAutoConfiguration$NonEmbeddedInMemoryDatabaseShutdownExecutor.destroy(DevToolsDataSourceAutoConfiguration.java:104)
	at org.springframework.beans.factory.support.DisposableBeanAdapter.destroy(DisposableBeanAdapter.java:256)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:571)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:543)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingleton(DefaultListableBeanFactory.java:1055)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:504)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingletons(DefaultListableBeanFactory.java:1062)
	at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:1057)
	at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1026)
	at org.springframework.context.support.AbstractApplicationContext$1.run(AbstractApplicationContext.java:945)
	- locked <0x00000000e1728680> (a java.lang.Object)
"Thread-9":
	at org.h2.command.dml.TransactionCommand.update(TransactionCommand.java:97)
	- waiting to lock <0x00000000e9c4dd08> (a org.h2.engine.Session)
	at org.h2.command.CommandContainer.update(CommandContainer.java:133)
	at org.h2.command.Command.executeUpdate(Command.java:267)
	- locked <0x00000000ecc99788> (a org.h2.engine.Session)
	at org.h2.jdbc.JdbcStatement.executeInternal(JdbcStatement.java:233)
	- locked <0x00000000ecc99788> (a org.h2.engine.Session)
	at org.h2.jdbc.JdbcStatement.execute(JdbcStatement.java:205)
	at com.zaxxer.hikari.pool.ProxyStatement.execute(ProxyStatement.java:95)
	at com.zaxxer.hikari.pool.HikariProxyStatement.execute(HikariProxyStatement.java)
	at org.springframework.boot.devtools.autoconfigure.DevToolsDataSourceAutoConfiguration$NonEmbeddedInMemoryDatabaseShutdownExecutor.destroy(DevToolsDataSourceAutoConfiguration.java:104)
	at org.springframework.beans.factory.support.DisposableBeanAdapter.destroy(DisposableBeanAdapter.java:256)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:571)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:543)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingleton(DefaultListableBeanFactory.java:1055)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:504)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingletons(DefaultListableBeanFactory.java:1062)
	at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:1057)
	at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1026)
	at org.springframework.context.support.AbstractApplicationContext$1.run(AbstractApplicationContext.java:945)
	- locked <0x00000000e6dacac0> (a java.lang.Object)
"Thread-45":
	at org.h2.command.dml.TransactionCommand.update(TransactionCommand.java:97)
	- waiting to lock <0x00000000ecc99788> (a org.h2.engine.Session)
	at org.h2.command.CommandContainer.update(CommandContainer.java:133)
	at org.h2.command.Command.executeUpdate(Command.java:267)
	- locked <0x00000000e9c4dd08> (a org.h2.engine.Session)
	at org.h2.jdbc.JdbcStatement.executeInternal(JdbcStatement.java:233)
	- locked <0x00000000e9c4dd08> (a org.h2.engine.Session)
	at org.h2.jdbc.JdbcStatement.execute(JdbcStatement.java:205)
	at com.zaxxer.hikari.pool.ProxyStatement.execute(ProxyStatement.java:95)
	at com.zaxxer.hikari.pool.HikariProxyStatement.execute(HikariProxyStatement.java)
	at org.springframework.boot.devtools.autoconfigure.DevToolsDataSourceAutoConfiguration$NonEmbeddedInMemoryDatabaseShutdownExecutor.destroy(DevToolsDataSourceAutoConfiguration.java:104)
	at org.springframework.beans.factory.support.DisposableBeanAdapter.destroy(DisposableBeanAdapter.java:256)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:571)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:543)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingleton(DefaultListableBeanFactory.java:1055)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:504)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingletons(DefaultListableBeanFactory.java:1062)
	at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:1057)
	at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1026)
	at org.springframework.context.support.AbstractApplicationContext$1.run(AbstractApplicationContext.java:945)
	- locked <0x00000000e916fee0> (a java.lang.Object)

Found 1 deadlock.

Duplicate issue #1870: MULTI_THREADED=TRUE will leave Spring Boot tests hanging after upgrading to 1.4.198
Created: 2019-04-17T22:02:18Z
After discussion in spring-projects/spring-boot#16512 I am filing here.
Seems that after Spring Boot upgraded to h2 1.4.199, it introduced a bug which leaves JUnit tests hanging under certain conditions. This is solved by either downgrading to 1.4.197 or setting the parameter MULTI_THREADED=FALSE.
https://github.com/spring-guides/tut-spring-boot-kotlin](https://github.com/spring-guides/tut-spring-boot-kotlin) is a repo that can be used to reproduce the issue by upgrading it to Spring Boot 2.1.4 and running all the test with ./gradlew test.

Closing comment (2019-04-18T07:40:34Z): i.e. duplicate of #1841