【问题标题】:A persistent connection with JDBC to MySQL使用 JDBC 到 MySQL 的持久连接
【发布时间】:2011-05-11 16:50:23
【问题描述】:

我有一个使用 JDBC 连接到 MySQL 的应用程序。在某些情况下,JDBC 连接会闲置数小时(甚至数天),并失去与 MySQL 的连接,然后在尝试执行查询时除外。最好的解决方案是什么?

【问题讨论】:

    标签: java mysql jdbc


    【解决方案1】:

    在有限的时间内保持连接打开是一种不好的做法。当数据库打开时间过长时,数据库将强制关闭。您应该编写 JDBC 代码,以便它始终关闭您获取它们的同一 try 块的 finally 块中的连接(以及语句和结果集),以防止像这样的资源泄漏。

    但是,在每次打嗝时获取连接确实是一项非常昂贵的任务,因此您希望使用连接池。体面的连接池将自行管理连接的打开、测试、重用和关闭。然而,这并不意味着您可以更改您的 JDBC 代码以从不关闭它们。您仍然需要关闭它们,因为这实际上会将底层连接释放回池以供将来重用。

    有几个连接池,例如 Apache DBCP 是单线程的,因此性能较差,C3P0 是多线程的,性能更好,Tomcat JDBC 用于您使用 Tomcat 并且不喜欢的情况由于性能不佳而使用内置 DBCP。

    您可以通过编程方式创建连接池,以下是 C3P0 的示例:

    ComboPooledDataSource dataSource = new ComboPooledDataSource();
    dataSource.setDriverClass("com.mysql.jdbc.Driver");
    dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/dbname");
    dataSource.setUser("username");
    dataSource.setPassword("password"); 
    

    在应用程序启动时执行一次,然后您可以如下使用它:

    Connection connection = null;
    // ...
    
    try {
        connection = dataSource.getConnection();
        // ...
    } finally {
        // ...
        if (connection != null) try { connection.close(); } catch (SQLException ignore) {}
    }
    

    当您在支持 JNDI 的容器(如 servletcontainer(例如 Tomcat)中运行时,您也可以将其声明为 java.sql.DataSource(Tomcat 特定手册 here)。然后它将使用 servletcontainer 提供的连接池设施。然后您可以按如下方式获取数据源:

    DataSource dataSource = (DataSource) new InitialContext().lookup("java:comp/env/jdbc/YourDataSourceName");
    

    【讨论】:

    • 为什么不将连接保留为类成员,在您打算使用时检查它是否关闭,如果关闭则启动新连接?除了暂时保留一点记忆之外,这会有什么问题?
    • @EB:这是线程不安全的。相关:stackoverflow.com/q/9428573 您应该为每个线程和事务使用一个完全独立的连接。它们可以在完成线程本地事务工作后保持打开并被重用,但这正是连接池所做的。连接池不会在物理上关闭连接,它只是保持打开状态并在释放之前对其进行测试(正如本文中已经回答的那样)
    【解决方案2】:

    在这里查看:

    基本上,您应该使用 DataSource 并在使用它之前始终执行 getConnection()。 DataSource,除非出现严重错误,否则会在必要时重新连接。

    【讨论】:

      【解决方案3】:

      有一些库,比如Apache's DBCP,可以做连接池。其中一部分是它们可以设置为在您使用它时自动测试连接(例如“SELECT NOW() FROM DUAL”或其他无害的东西),并在必要时自动透明地重新建立连接,允许您的应用程序假装连接是永恒的。

      【讨论】:

      • 这是要走的路。您甚至可以将其设置为在将连接返回给客户端之前执行一个虚拟 SELECT,这样您就知道它会起作用。
      猜你喜欢
      • 2011-01-16
      • 2012-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-30
      • 1970-01-01
      • 1970-01-01
      • 2014-11-11
      相关资源
      最近更新 更多