13 messages in com.mysql.lists.javaRe: com.jdbc.mysql.Driver deadlock (C...
FromSent OnAttachments
Dane Foster16 Apr 2003 11:11 
Slava Imeshev16 Apr 2003 11:26 
Jeff Mathis16 Apr 2003 11:36 
Morten Norby Larsen16 Apr 2003 11:41 
Mark Matthews16 Apr 2003 11:41 
Dane Foster16 Apr 2003 11:42 
Mark Matthews16 Apr 2003 11:57 
Slava Imeshev16 Apr 2003 12:08 
Jeff Mathis16 Apr 2003 12:12 
Morten Norby Larsen16 Apr 2003 12:30 
Tim Endres16 Apr 2003 12:58 
Jeff Mathis16 Apr 2003 13:56 
Mark Matthews16 Apr 2003 14:28 
Subject:Re: com.jdbc.mysql.Driver deadlock (Connector/J v 3.0.7.stable)
From:Dane Foster (dfos@equitytg.com)
Date:04/16/2003 11:42:23 AM
List:com.mysql.lists.java

Hello Slava, your point is well taken but if you examine the code I've included you will see that there is no Thread contention for the DriverManager class by the Threads. Only one of them ever calls getConnection which suggests that the problem is not as you suggest.

----- Original Message ----- From: "Slava Imeshev" <imes@yahoo.com> To: "Dane Foster" <dfos@equitytg.com>; <ja@lists.mysql.com> Sent: Wednesday, April 16, 2003 14:26 Subject: Re: com.jdbc.mysql.Driver deadlock (Connector/J v 3.0.7.stable)

Hi Dane,

It's a well known problem of a DriverManager, not of MySQL. It's a common sense that DriverManager should NOT be used in multithreaded environment (or, better, not used at all) and that direct driver loading should be used instead, i.e.:

Driver driver = (Driver)Class.forName("my.sql.Driver").newInstance(); Connection conn = driver.connect();

Hope this helps.

Regards,

Slava Imeshev

--- Dane Foster <dfos@equitytg.com> wrote:

Hi Mark. I think I've found a bug in the com.jdbc.mysql.Driver class. Unfortunately, my debugger doesn't/can't show the innards of Connector/J's Driver class so I'm unable to tell you exactly where the problem is occuring. I've included some code below that reproduces the bug and has comments detailing the nature of the bug.

<SysConfig> Dual P3 600MHZ 512 MB WIN2k svc3 JRE 1.4.1_02 standard Connector/J 3.0.7 stable </SysConfig>

<code> // The following two classes and their interaction are supposed to accomplish the following: // The first class represents the 'main' Thread and it starts a child Thread then waits for input on STDIN. // The child Thread tries to establish a JDBC connection to a database then closes the connection and exits.

// What happens in reality is, the child Thread is not able to establish a connection because the // java.lang.DriverManager.getConnection method (appears to me as if it) cannot complete/return while another // Thread is blocked on java.lang.System.in. W/ tracing turned on I've discovered that the deadlock begins at // line 512 of the DriverManager class, which is the point were it calls the driver (com.mysql.jdbc.Driver)'s // connect method. I haven't been able to pinpoint w/ my debugger where exactly in the Driver's code the hang // happens and as a mental exercise, I can't figure out what System.in has to do w/ establishing a JDBC // connection. Nevertheless, the code below indicates that there is some sort of relationship between them.

import java.sql.*; import java.io.*;

public class TestCase { boolean initialized = false;

Thread child;

void startThread() throws Exception { child = new TestChild( this ); child.start(); Thread.sleep( 1000 ); initialized = true; }

public static void main( String args[] ) throws Exception { Class.forName( "com.mysql.jdbc.Driver" ); byte[] bucket = new byte[ 4 ]; DriverManager.setLogWriter( new PrintWriter( System.err ) ); TestCase _this = new TestCase(); _this.startThread();

while( true ) { int eof = System.in.read( bucket ); String command = new String( bucket, 0, eof, "us-ascii" ); if( "quit".equals( command ) ) break; } _this.child.join(); } }

class TestChild extends Thread { TestCase parent;

TestChild( TestCase e ) { this.parent = e; }

public void run() { while( !parent.initialized ) this.yield(); try { String jdbc = "jdbc:mysql://lab.equitytg.local/DirectFile2"; System.out.print( "Establishing a db connection .... " ); Connection conn = DriverManager.getConnection( jdbc ); System.out.print( "OK\nClosing conn ...." ); conn.close(); System.out.println( "OK" ); } catch( Throwable t ) { t.printStackTrace(); return; } } } </code>