1

我一直在尝试使用 Tomcat 的本机连接池功能来避免我的 Java Web 项目中的连接超时,但似乎我仍然不走运。

我已经放入mysql-connector-java-5.1.23-bin.jar文件WEB-INF/lib夹,创建了一个META-INF/context.xml这样的:

<?xml version="1.0" encoding="UTF-8"?>
<Context>
    <Resource name="jdbc/TheDatabase" auth="Container"
            type="javax.sql.DataSource" driverClassName="com.mysql.jdbc.Driver"
            maxActive="100" maxIdle="30" maxWait="1000"
            poolPreparedStatements="true" maxOpenPreparedStatements="100"
            username="user" password="pass"
            url="jdbc:mysql://localhost:3306/my_database"/>
</Context>

这就是我所做的:

public static init() {
    ...
    sqlDataSource = (DataSource) new InitialContext().lookup("java:comp/env/jdbc/TheDatabase");
    ...
}

public static ArrayList<ResultSet> dbRead() {
    Connection conn = sqlDataSource.getConnection();
    Statement stmt = null;
    try {
        stmt = conn.createStatement();
        ResultSet res = stmt.executeQuery("SELECT * FROM the_table");
        ...
        res.close();

        return out;
    } catch (SQLException e) {
        // Logging stuff
        return null;
    } finally {
        if (stmt != null)
            try {if (!stmt.isClosed()) stmt.close();}
            catch (SQLException e) {/* Logging stuff */}
        if (conn != null)
            try {if (!conn.isClosed()) conn.close();}
            catch (SQLException e) {/* Logging stuff */}
    }
}

每当我在通过dbRead后调用该函数wait_timeout时,我都会得到:

Communications link failure

The last packet successfully received from the server was 1.818.697 milliseconds
ago. The last packet sent successfully to the server was 0 milliseconds ago.

带有 SQL 状态08S01

我认为这是因为一些不正确的关闭,但似乎并非如此。

4

4 回答 4

1

尝试添加验证查询,然后让我现在。我希望这能解决问题。
如果没有,则将localhost 更改为您机器的 IP(您也可以测试 127.0.0.1)

<?xml version="1.0" encoding="UTF-8"?>
<Context>
    <Resource name="jdbc/TheDatabase" auth="Container"
            type="javax.sql.DataSource" driverClassName="com.mysql.jdbc.Driver"
            maxActive="100" maxIdle="30" maxWait="1000"
            poolPreparedStatements="true" maxOpenPreparedStatements="100"
            username="user" password="pass" validationQuery="select now()" 
            url="jdbc:mysql://192.168.1.1:3306/my_database"/>
</Context>
于 2013-10-01T21:30:00.623 回答
0

似乎我需要添加到<Resource>定义中的只是validationQuery属性。不autoReconnect,不autoReconnectForPools,什么都没有。这很有效:

<Resource name="jdbc/TheDatabase" auth="Container"
        type="javax.sql.DataSource" driverClassName="com.mysql.jdbc.Driver"
        maxActive="100" maxIdle="30" maxWait="1000"
        poolPreparedStatements="true" maxOpenPreparedStatements="100"
        username="user" password="pass" validationQuery="SELECT 1"
        url="jdbc:mysql://localhost:3306/my_database"/>

该属性甚至不在MySQL 文档中,所以我不知道它的存在。现在我怀疑其他一些属性也有任何影响......

于 2013-10-01T14:01:41.957 回答
0

尝试使用这个东西:

<Resource name="jdbc/myDataSource" auth="Container" type="javax.sql.DataSource"
            maxActive="100" maxIdle="30" maxWait="10000"
            username="user" password="pass" 
            driverClassName="com.mysql.jdbc.Driver"
            url="jdbc:mysql://localhost/my_database?autoReconnect=true"
            logAbandoned="true" removeAbandoned="true" 
            removeAbandonedTimeout="60" />
于 2013-10-01T11:32:59.840 回答
0

将 autoReconnect 设置为 true,默认为 false。如需更多信息或帮助

autoReconnect 驱动程序是否应该尝试重新建立陈旧和/或失效的连接?如果启用,驱动程序将为在陈旧或死连接上发出的查询抛出异常,这些查询属于当前事务,但会在新事务中的连接上发出下一个查询之前尝试重新连接。不建议使用此功能,因为当应用程序无法正确处理 SQLExceptions 时,它会产生与会话状态和数据一致性相关的副作用,并且仅在您无法配置应用程序以处理由以下原因导致的 SQLExceptions 时使用正确的死和陈旧的连接。或者,作为最后一个选项,研究将 MySQL 服务器变量“wait_timeout”设置为较高的值,而不是默认值 8 小时。假 1.1

autoReconnectForPools 使用适合连接池的重新连接策略(默认为“false”) false 3.1.3

见 mysql 文档

于 2013-10-01T11:28:19.220 回答