Mantis - Quercus
Viewing Issue Advanced Details
1497 major always 12-08-06 05:37 03-20-07 10:41
dberry  
nam  
normal  
closed 3.1.0  
fixed  
none    
none 3.1.1  
0001497: DB Connection Management error using Mysqli
If you open a connection, close a connection, then open a new connection you get an acception that the connection is closed.

java.lang.IllegalStateException: connection is closed
    at com.caucho.sql.UserConnection.getMConn(UserConnection.java:832)
    at com.caucho.sql.UserConnection.setAutoCommit(UserConnection.java:616)
    at com.caucho.quercus.lib.db.JdbcConnectionResource.setAutoCommit(JdbcConnectionResource.java:577)
    at com.caucho.quercus.lib.db.Mysqli.autocommit(Mysqli.java:170)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:585)
    at com.caucho.quercus.env.JavaMethod.invoke(JavaMethod.java:76)
    at com.caucho.quercus.env.JavaInvoker.call(JavaInvoker.java:533)
    at com.caucho.quercus.program.JavaClassDef.callMethod(JavaClassDef.java:471)
    at com.caucho.quercus.env.JavaValue.callMethod(JavaValue.java:190)
    at com.caucho.quercus.expr.MethodCallExpr.eval(MethodCallExpr.java:99)
    at com.caucho.quercus.program.ExprStatement.execute(ExprStatement.java:63)
    at com.caucho.quercus.program.BlockStatement.execute(BlockStatement.java:99)
    at com.caucho.quercus.program.QuercusProgram.execute(QuercusProgram.java:234)
    at com.caucho.quercus.page.InterpretedPage.execute(InterpretedPage.java:60)
    at com.caucho.quercus.page.QuercusPage.executeTop(QuercusPage.java:114)
    at com.caucho.quercus.servlet.QuercusServlet.service(QuercusServlet.java:241)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:92)
    at com.caucho.server.dispatch.ServletFilterChain.doFilter(ServletFilterChain.java:103)
    at com.caucho.server.webapp.WebAppFilterChain.doFilter(WebAppFilterChain.java:167)
    at com.caucho.server.dispatch.ServletInvocation.service(ServletInvocation.java:226)
    at com.caucho.server.http.HttpRequest.handleRequest(HttpRequest.java:263)
    at com.caucho.server.port.TcpConnection.run(TcpConnection.java:477)
    at com.caucho.util.ThreadPool$Item.runTasks(ThreadPool.java:591)
    at com.caucho.util.ThreadPool$Item.run(ThreadPool.java:513)
    at java.lang.Thread.run(Thread.java:613)

Here is a test case:

<?php
// This is a test to find out what is causing problems with the closed connection
?>

<html>
<head>
</head>

<body>
<?php


            $db = mysqli_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASS, MYSQL_DB, MYSQL_PORT);
            $db->autocommit(false);
            $db->close();
            $db1 = mysqli_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASS, MYSQL_DB, MYSQL_PORT);
            $db1->autocommit(false);
            $db1->close();
?>
</body>
</html>

Notes
(0001714)
dberry   
01-11-07 10:44   
Here is an updated test case. Originally I thought the problem was the fact that env.getConnection() did not check to see if connection was closed prior to being handed out, but the problem is deeper than that. You are handing out connections with a total disregard for the concept of a transaction. My recommendation is to do the connection pooling in MysqliModule so that you will not handout connections that are already in use.

Here is the new test case.

$db = mysqli_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASS, MYSQL_DB, MYSQL_PORT);
$db->autocommit(false);
$db->close();
syslog(LOG_ERR,"Performed First Close.");

$db1 = mysqli_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASS, MYSQL_DB, MYSQL_PORT);
$db1->autocommit(false);
$db->close();
syslog(LOG_ERR,"Performed Second Close.");
            
// Now lets do a nested close to break this connection cache.
$db = mysqli_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASS, MYSQL_DB, MYSQL_PORT);
$db1 = mysqli_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASS, MYSQL_DB, MYSQL_PORT);
$db1->autocommit(false);
$db->close();
syslog(LOG_ERR,"Performed Third Close.");
            
$db->autocommit(false);
$db->close();
syslog(LOG_ERR,"Performed Fourth Close.");
(0001715)
dberry   
01-11-07 11:23   
TYPO in the test case here it is again:

$db = mysqli_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASS, MYSQL_DB, MYSQL_PORT);
$db->autocommit(false);
$db->close();
syslog(LOG_ERR,"Performed First Close.");

$db1 = mysqli_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASS, MYSQL_DB, MYSQL_PORT);
$db1->autocommit(false);
$db->close();
syslog(LOG_ERR,"Performed Second Close.");
            
// Now lets do a nested close to break this connection cache.
$db = mysqli_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASS, MYSQL_DB, MYSQL_PORT);
$db1 = mysqli_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASS, MYSQL_DB, MYSQL_PORT);
$db1->autocommit(false);
$db1->close();
syslog(LOG_ERR,"Performed Third Close.");
            
$db->autocommit(false);
$db->close();
syslog(LOG_ERR,"Performed Fourth Close.");
(0001716)
dberry   
01-11-07 11:27   
Here is the modified env.getConnection(). It is a removal of the caching logic:

 /**
   * Returns the configured database.
   */
  public Connection getConnection(String driver, String url,
                                  String userName, String password)
    throws Exception
  {
    DataSource database = _quercus.getDatabase();

    if (database != null)
      return database.getConnection();

    database = _quercus.findDatabase(driver, url);
    
    if (userName == null || userName.equals(""))
      return database.getConnection();
    
    return database.getConnection(userName, password);
      
  }
(0001720)
nam   
01-16-07 10:06   
php/1418 ('using closed connection' fixed)

Quercus hands out connections based on the (host, username, password) tuple. PHP scripts tend to open a new connection without closing the previous connection. For most cases, PHP scripts use the new connection exclusively and the race condition where multiple open connections to the same database tuple are actively used is a non-issue for real applications.
(0001778)
nam   
03-20-07 10:41   
php/1f19