Description:
According to the VARIABLE "wait_timeout" (default: 28800 seconds) in the manual,
a running MySQL daemon clears up idle connections if
their "idle period" > "wait_timeout".
This works fine on my daemon. But however, after such clear-up happens,
when I checked my connection objects inside my java ConnectionPool,
they all returned as "NOT CLOSED". It is demonstrated as follows:
CODE:
=====
// When idle time > wait_timeout
....
Connection conn = connPool.getConnection();
System.out.println("Is conn closed: "+conn.isClosed());
....
Output:
=======
Is conn closed: false
============= End of output ============
Furthermore, when I create a statement with the above Connection object,
followed by executing a simple query,
sometimes a "StackOverflowError" is thrown instead of an expected SQLException,
demonstrated as follows:
CODE:
=====
....
try {
System.out.println("checkpoint 1");
Statement s = conn.createStatement();
System.out.println("checkpoint 2");
ResultSet r = s.executeQuery("show tables");
System.out.println("checkpoint 3");
} catch(SQLException e) {
System.out.println("SQLException catched!!! \n");
e.printStackTrace();
} catch(Exception e) {
System.out.println("Exception catched!!! \n");
e.printStackTrace();
} catch (Throwable t) {
System.out.println("Throwable catched!!! \n");
t.printStackTrace();
}
....
Expected output:
================
checkpoint 1
checkpoint 2
SQLException catched!!!
SQLException ConnectionPool_PassedValidationTest Sun Jun 22 19:01:55 EST 2003
java.sql.SQLException: Communication link failure: java.io.IOException
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:1604)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:886)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:945)
at com.mysql.jdbc.MysqlIO.sqlQuery(MysqlIO.java:917)
at com.mysql.jdbc.Connection.execSQL(Connection.java:1841)
at com.mysql.jdbc.Connection.execSQL(Connection.java:1775)
at com.mysql.jdbc.Statement.executeQuery(Statement.java:1220)
.............. other unrelated classes (provided on request) .............
UN-Expected output:
===================
checkpoint 1
checkpoint 2
Throwable catched!!!
java.lang.StackOverflowError
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:69)
at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:127)
at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:1478)
at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:1405)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:879)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:945)
at com.mysql.jdbc.MysqlIO.sqlQuery(MysqlIO.java:917)
at com.mysql.jdbc.Connection.execSQL(Connection.java:1841)
at com.mysql.jdbc.Connection.execSQL(Connection.java:1787)
at com.mysql.jdbc.Connection.execSQL(Connection.java:1768)
<<< A >>>
at com.mysql.jdbc.Connection.rollbackNoChecks(Connection.java:1369)
at com.mysql.jdbc.Connection.rollback(Connection.java:1356)
at com.mysql.jdbc.Connection.close(Connection.java:1028)
at com.mysql.jdbc.Connection.cleanup(Connection.java:2050)
at com.mysql.jdbc.Connection.execSQL(Connection.java:1853)
at com.mysql.jdbc.Connection.execSQL(Connection.java:1787)
at com.mysql.jdbc.Connection.execSQL(Connection.java:1768)
<<< B >>>
.............. repeat <<< A >>> to <<< B >>> many times ..................
at com.mysql.jdbc.Connection.rollbackNoChecks(Connection.java:1369)
at com.mysql.jdbc.Connection.rollback(Connection.java:1356)
at com.mysql.jdbc.Connection.close(Connection.java:1028)
============= End of output ============
I wonder if this is either a bug of the Connector/J or a bug of the MySQL daemon.
Shouldn't conn.isClosed() returns "true" if the connection has been forced
to shutdown by the MySQL daemon according to wait_timeout?
And even if it doesn't, why would something other than a java Exception be thrown?
Please have a look at this problem.
I use:
- Connector/J 3.0.7 driver,
- J2SE 1.4.1_03,
- Red Hat Linux 8.0 w/kernal 2.4.18 and
- MySQL 4.0.12
Wilson Chan
How to repeat:
Step 1:
- Set the GLOBAL and SESSION wait_timeout in MySQL to 10 seconds.
Step 2:
- Run the following program by typing "java MySQLStackErrorTest"
- There is a possibility that the StackOverflowError won't appear
==== START OF PROGRAM ====
import java.sql.*;
public class MySQLStackErrorTest {
/**
* Please alter this idle period accordingly.
* It only works when it is
* > wait_timeout
* in MySQL.
*/
public static final int IDLE_PERIOD = 15 * 1000;
public static void main(String args[]) throws Throwable {
/**
* Please try a different driver name if this doesn't work for you
*/
Class.forName("org.gjt.mm.mysql.Driver");
Connection conn = getConnection();
do {
try {
System.out.println("Connection closed? "+conn.isClosed());
Statement s = conn.createStatement();
System.out.println("StatementCreated");
ResultSet r = s.executeQuery("Show tables");
System.out.println("Query OK");
Thread.sleep(IDLE_PERIOD);
} catch (SQLException e) {
System.out.println();
e.printStackTrace();
System.out.println();
Thread.sleep(3000);
}
} while (true);
}
public static Connection getConnection() throws SQLException {
/**
* Please alter the URL, USERNAME and PASSWORD accordingly
*/
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mysql",
"root",
"root");
return conn;
}
}
==== END OF PROGRAM ====