Bug #19416 Potential deadlock in JDBC driver

Submitted: 28 Apr 2006 7:56 Modified: 2 Jun 2006 17:22
Reporter: Andy Seaborne Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / J Severity:S2 (Serious)
Version:5.0.0-beta OS:
Assigned to: CPU Architecture:Any

[28 Apr 2006 7:56] Andy Seaborne
Description:
More for http://bugs.mysql.com/bug.php?id=14972 (not being the original submitter, I can't change its status)

Codebase: Connector/J 5.0.0.-beta (timestamp in the zip around Dec 2005, that is after 14972)

I have had the following deadlock arise bewteen
ServerPreparedStatement.serverPrepare and Connection.unregisterStatement
(annotated stacktrace below) which looks similar to the original bug report.

This isn't the only one I've found: below ------ I include another I turned
up.

The trouble is a deadly embrace caused by the order locks are obtained.  The
lock order is:
PatternStage-41:
   connection (outer)
     this.connection.getMutex()

Thread-23 lock
   connection.getMutex()
     connection 

Thread [PatternStage-41] (Suspended)
    ServerPreparedStatement.serverPrepare(String) line: 1311
**** synchronized (this.connection.getMutex()) {
    ServerPreparedStatement.<init>(Connection, String, String) line: 316
    Connection.prepareStatement(String, int, int) line: 4377
    Connection.prepareStatement(String) line: 4315
**** synchronized method
    SQLCache.doPrepareSQLStatement(String) line: 289
    SQLCache.getPreparedSQLStatement(String, String[]) line: 271
    SQLCache.getPreparedSQLStatement(String, String) line: 318
    PSet_ReifStore_RDB.findReifTripleMatch(TripleMatch, IDBID) line: 177
    SpecializedGraphReifier_RDB.find(TripleMatch,
SpecializedGraph$CompletionFlag) line: 414
    GraphRDB.graphBaseFind(TripleMatch) line: 431
    GraphRDB(GraphBase).find(TripleMatch) line: 224
    GraphRDB(GraphBase).graphBaseFind(Node, Node, Node) line: 244
    GraphRDB(GraphBase).find(Node, Node, Node) line: 241
    QueryTriple$SimpleApplyer.find(Domain) line: 141
    QueryTriple$SimpleApplyer.applyToTriples(Domain, Matcher, StageElement)
line: 145
    StageElement$FindTriples.run(Domain) line: 50
    PatternStage(PatternStageBase).run(Pipe, Pipe, StageElement) line: 43
    PatternStageBase$1.run() line: 53
Thread [Thread-23] (Suspended)
    Connection.unregisterStatement(Statement) line: 5380
**** synchronized
    ServerPreparedStatement(Statement).realClose(boolean, boolean) line: 1863
    ServerPreparedStatement(PreparedStatement).realClose(boolean, boolean) line:
1722
**** inside synchronized (this.connection.getMutex())

    ServerPreparedStatement.realClose(boolean, boolean) line: 906
    ServerPreparedStatement.close() line: 467
    DBQueryStage.run(Pipe, Pipe) line: 111
    DBQueryStage$1.run() line: 143

----------------------------
Abbreviated stack trace showing the two threads that seem to be deadlocked:

Jena-Misc DBtest [Java Application]
    dev.DBtest at localhost:3929
        Thread [main] (Suspended)
        Thread [Thread-1] (Suspended)
            Connection.getCatalog() line: 3194
*** synchronized            
            ServerPreparedStatement(PreparedStatement).execute() line: 709
*** inside synchronized (this.connection.getMutex())
            DBQueryStage.run(Pipe, Pipe) line: 76
            DBQueryStage$1.run() line: 136
        Thread [PatternStage-4] (Suspended)
        Thread [Thread-2] (Suspended)
            ServerPreparedStatement.serverPrepare(String) line: 1312
*** inside synchronized (this.connection.getMutex())
            ServerPreparedStatement.<init>(Connection, String, String) line:
316
            Connection.prepareStatement(String, int, int) line: 4377
*** synchronized
            Connection.prepareStatement(String) line: 4315
            DBQueryStage.run(Pipe, Pipe) line: 64
            DBQueryStage$1.run() line: 136
    C:\Program Files\Java\jdk1.5.0_06\bin\javaw.exe (26-Apr-2006 17:02:54)

How to repeat:
This has been difficult to cut down to something small.  It currently happens everytime with our test [*] suite but reducing the test suite tends to change the situation. It happens on both 2CPU workstations and 1CPU portables running Java 1.5 or 1.4 on Windows XP

[*] http://jena.sourceforge.net - An RDF framework.

Suggested fix:
A possible fix might be to have only one lock object
(the connection), so 

synchronized (this.connection.getMutex()) becomes

synchronized (this.connection)

(in Connection, ServerPreparedStatement etc)

This has the same effect as 

Object getMutex() { 
 ...
  return this ;
}
[30 May 2006 19:09] Mark Matthews
Have you tried a nightly build of 5.0 from http://downloads.mysql.com/snapshots.php#connector-j?

We've loosened up the synchronization quite a bit, and it will probably solve your problem.
[2 Jun 2006 17:22] Andy Seaborne
I tried mysql-connector-java-5.0-nightly-20060601 and 5.0.0-beta on exactly the same setup.

The nightly build passes our test suite where the 5.0.0-beta was locking up.

    Thanks!
    Andy

Portions of this website are copyright © 2001, 2002 The PHP Group

Page generated in 0.038 sec. using MySQL 8.4.7-u6-cloud

Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the respective copyright holders.
It is not reviewed in advance by Oracle and does not necessarily represent the opinion of Oracle or any other party.