Resolving an H2 Deadlock in Spring Social

Deadlocks occur when database access is blocked by conflicting processes, with neither able to complete execution. This isn’t unique to Spring Social certainly, nor to Spring, and it rarely occurs at all. But it happened to me whenever Spring Social created a connection to add or retrieve Social User data with H2. Everything worked great with MySQL, but H2 produced a database deadlock and caused my application to hang.

This thread dump gives you an idea of the conflict at work, where the application is running but multiple processes are waiting on a H2 data connection. “Waiting, waiting, waiting…in Casablanca.”

An example of triggering the deadlock in Spring Social occurred for me when creating a new Social User after Signup. The User is authorized with the OAuth Provider (Facebook in this case) and returned to /signup/[GET] where the User completes the Signup Form. On [submit] the User is created locally as usual with Spring Security and the appropriate H2 tables populated. Then Spring Social creates a new H2 connection to populate the UserConnection table in /signup/[POST] providerSignInUtils.doPostSignUp()

In ProviderSignInUtils we see where the connection is created.

The Fix

Okay, what you’ve been waiting for. When creating a DataSource in Spring it’s easy to configure the Connection Pool. Here in the H2Config class we added a new property to our Tomcat BasicDataSource dataSource, setMaxTotal(). We increased the number of connections to “no limit” which is fine since H2 is strictly a development and testing configuration.

Source Code Notes for this Post

All source code discussed in this post can be found in my NixMash Spring GitHub repo and viewed online here.