【问题标题】:MySQL connection remains after close(), with a thin wrapperMySQL 连接在 close() 之后仍然存在,带有一个瘦包装器
【发布时间】:2012-02-27 08:16:48
【问题描述】:

我写了一个Java程序,连接到MySQL数据库,立即关闭,然后休眠一段时间终止。

    Connection conn = DriverManager.getConnection(conn_str);
    conn.close();
    Thread.sleep(30 * 1000);

上面的代码工作得很好。 conn 会在调用 close() 后立即关闭,并且 sleep() 期间不会出现连接。

之后,我写了一个瘦连接包装器:

    public static Connection CreateConnection(String _connectionStr) throws SQLException {
        Connection c = null;
        c = DriverManager.getConnection(_connectionStr);
        return c;
    }

修改后的代码是:

    Connection conn = ConnectionWrapper.CreateConnection(conn_str);
    conn.close();
    Thread.sleep(30 * 1000);

我希望这两个没有区别,但是对于后一种情况,连接一直保持未关闭,直到程序终止(这里是 30 秒)。这在以前的代码中不会发生。

我检查了mysqladmin extend-status | grep connected 的行为,查看了Threads_connected 的值。

我想使用后一个包装器进行代码抽象。如果您对强制关闭连接的行为或解决方法有任何想法,请告诉我。

谢谢,

--

已编辑:修复了“包装器”代码。这是我的错。

已编辑:来自 mysqladmin 的连接数默认为 1(诊断性连接数)。后者代码运行时数字变为 2,而前者代码运行时数字为 2。

【问题讨论】:

  • 您尚未创建包装器。您已经创建了一个方法,您可以调用该方法来获得连接(这样做时忽略了遵守 Java 命名约定)。两个代码 sn-ps 是严格等价的。您的诊断可能有误。
  • 您实际上并没有直接调用方法CreateConnection(ConnectionType, String)。也许你在 CreateConnection(String) 方法中做了一些不同的事情?
  • 我相信两者是等价的,但有不同的行为。我很困惑。
  • CreateConnection(String) 是正确的。我解决了这个问题。谢谢。

标签: java mysql


【解决方案1】:

你能试试这个代码吗...看看错误输出会是什么...

try{
 con.close();
  if (con.isClosed()) 
    System.out.println("Connection closed.");
} catch (java.lang.ClassNotFoundException e) {
  System.err.println("ClassNotFoundException: " +e.getMessage());
} catch (SQLException e) {
  System.err.println("SQLException: " +e.getMessage());
}

【讨论】:

  • 代码输出“连接已关闭”。也不例外。 isClosed() 表示连接已关闭,但连接在mysqladmin 命令(和netstat)中保持未关闭...
  • 您确定打开的连接不是您的诊断连接(由 mysqladmin 在尝试获取状态时创建)?
  • 我很确定。连接数为“1”我开始监控,连接数增加。
【解决方案2】:

我认为这是连接池(一个节省重新连接时间的想法......)

看看这篇文章:

http://dev.mysql.com/tech-resources/articles/connection_pooling_with_connectorj.html

【讨论】:

  • 我查看了这篇文章,但我不确定我的问题与文档有关。在上面的代码中,我对文章中的代码也是这样做的,不是吗?
  • 尝试禁用池化再查看
【解决方案3】:

好的,很抱歉看到你的代码如此麻木......正如你所看到的......你在方法中创建了一个连接......所以这意味着当你摆脱它时方法...您将无法关闭该连接(变量 c),因为您只是通过使用返回(这是您的变量 conn)将连接复制到另一个变量上...并且连接仍然存在。 尝试为您的包装器创建一个类而不是方法

【讨论】:

  • 嗯,,,好的。也许我明白。它类似于引用计数 GC 的问题。我创建一个类。非常感谢。
  • 我同意@JBNizet 的观点。尽管它被任意数量的其他变量引用,您仍可以关闭连接。
  • 哦,真的吗?如果是这样,为什么我不能确定关闭连接? isClose() 表示连接已关闭但mysqladmin表示连接保持打开状态,当我增加连接数进行测试时,它达到了连接上限...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-03
  • 1970-01-01
相关资源
最近更新 更多