Deadlock when using JDBC from two separate threads with two separate drivers

Description

In `clojure.java.jdbc`, it is possible for the function `get-connection` to call `clojure.lang.RT/loadClassForName` on the driver's classname. JDBC drivers have a static initializer to register themselves with `java.sql.DriverManager` upon load. However, `DriverManager`, as part of its static initializer, loads every implementation of `Driver` on the classpath. This causes an insidious bug when trying to use JDBC from two separate threads where each thread is using a different driver.

For example, if thread A tries to call `get-connection` with a db-spec using driver X, and thread B tries to call `get-connection` with a db-spec using driver Y, then thread A will load driver X which in turn loads `DriverManager`, which again in turn tries to load all drivers on the classpath, including driver Y. If driver Y is simultaneously being loaded by thread B, then driver Y will be trying to load `DriverManager` which is trying to load driver Y, thus creating deadlock. This behaviour can be reliably reproduced using the Clojure files attached.

I am not sure if this is even the responsibility of JDBC to fix. If you want to patch it on the JDBC side, it is easily possible to do so by making sure `DriverManager` is loaded before trying to load the driver.

Environment

Ubuntu 16.04, Leiningen

Attachments

3
  • 18 Oct 2016, 06:29 AM
  • 06 Oct 2016, 07:57 AM
  • 06 Oct 2016, 07:57 AM

Activity

Show:

Sean Corfield March 1, 2017 at 6:55 PM

0.7.0-alpha2 includes this fix.

Sean Corfield November 25, 2016 at 4:17 AM

Thank you for verifying that Roger!

Rogan Morrow November 25, 2016 at 1:21 AM

I tested master and it no longer deadlocks. Thanks for the fix.

Sean Corfield November 22, 2016 at 7:28 AM

Should be fixed in 0.7.0-alpha2

Sean Corfield November 22, 2016 at 7:28 AM

Can you try the latest master version (which force-loads DriverManager prior to calling classForName on the driver) to see if it solves this issue?

Completed

Details

Assignee

Reporter

Priority

Created October 6, 2016 at 7:57 AM
Updated March 1, 2017 at 6:55 PM
Resolved March 1, 2017 at 6:55 PM