Bug #1101 DriverManager.getConnection() is too slow when connection can't be made
Submitted: 19 Aug 2003 23:38 Modified: 20 Aug 2003 6:15
Reporter: Samo Login Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / J Severity:S4 (Feature request)
Version:3.0.8 OS:Java
Assigned to: Mark Matthews CPU Architecture:Any

[19 Aug 2003 23:38] Samo Login
Description:
The problem is not really in Connector/J, but in Java. and the problem is, that java.sql.DriverManager.getConnection() is synchronized. So when you try to make a connection to a MySQL database on a host that is down, you won't be able to make a connection to any other host using JDBC (including non-MySQL databases). This is a serious problem which Sun is not taking serious enough.

How to repeat:
Connect to a MySQL on a machine that is down (or to a non-existing machine). Wat you get is something like "Thread-6". As the getConnection() is synchronized, all following calls will look like "Thread-7".

"Thread-7" prio=5 tid=0x007a6300 nid=0x53c waiting for monitor entry [1874f000..1874fd98]
       at java.sql.DriverManager.getConnection(DriverManager.java:138)
       - waiting to lock <0x14152888> (a java.lang.Class)
       at si.noviforum.util.DatabasePing$AcceptThread.run(DatabasePing.java:72)

"Thread-6" prio=5 tid=0x007a50c0 nid=0x552 runnable [1870f000..1870fd98]
       at java.net.PlainSocketImpl.socketConnect(Native Method)
       at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:305)
       - locked <0x100570d0> (a java.net.PlainSocketImpl)
       at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:171)
       at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:158)
       at java.net.Socket.connect(Socket.java:452)
       at java.net.Socket.connect(Socket.java:402)
       at java.net.Socket.<init>(Socket.java:309)
       at java.net.Socket.<init>(Socket.java:124)
       at com.mysql.jdbc.StandardSocketFactory.connect(StandardSocketFactory.java:124)
       at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:198)
       at com.mysql.jdbc.Connection.createNewIO(Connection.java:1640)
       at com.mysql.jdbc.Connection.<init>(Connection.java:491)
       at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:346)
       at java.sql.DriverManager.getConnection(DriverManager.java:512)
       - locked <0x14152888> (a java.lang.Class)
       at java.sql.DriverManager.getConnection(DriverManager.java:140)
       - locked <0x14152888> (a java.lang.Class)
       at si.noviforum.util.DatabasePing$AcceptThread.run(DatabasePing.java:72)

Suggested fix:
So what you really could do is to make your connecting code more robust - it should fail faster if there is no MySQL server to connect to. This will not fix the problem, but will at least do some good :)
[20 Aug 2003 6:15] Mark Matthews
See the 'connectTimeout' and 'socketTimeout' parameters you can pass in your JDBC URL to have the driver timeout 'dead' hosts more quickly. The full description is in table 2.1 in the docs at: http://www.mysql.com/documentation/connector-j/index.html