【问题标题】:How to get around a JDBC connection to an Oracle DB from closing (SQLRecoverableException Closed Connection)?如何通过关闭(SQLRecoverableException Closed Connection)绕过与 Oracle DB 的 JDBC 连接?
【发布时间】:2017-01-31 17:05:51
【问题描述】:

我编写了以下代码来连接到 Oracle 数据库。这用于 REST API。我正在连接的数据库将 IDLE_TIME 参数设置为 30 分钟(无法更改)。如果数据库连接空闲超过 30 分钟,则会抛出以下错误:“java.sql.SQLRecoverableException: Closed Connection”。引发此错误后,API 将停止工作。我该如何解决这个问题?

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.Properties;
import java.util.Queue;
import java.util.ResourceBundle;
import java.sql.SQLRecoverableException;
import oracle.jdbc.driver.*;
import oracle.jdbc.pool.*;


public class OrcConnector {

    private Queue<Connection> connections;

    private int maxConnections;

    private static final int MAX_CONNECTIONS_DEFAULT = 10;

    public OrcConnector() {

        connections = new LinkedList<Connection>();
        maxConnections = MAX_CONNECTIONS_DEFAULT ;

    }

    public synchronized int getMaxConnections(){
        return maxConnections;
    }

    public synchronized void setMaxConnection (int maxConnections) {
        this.maxConnections = maxConnections;
    }

    public synchronized ConnWrapper getConnection() throws SQLException, BusyConnections {
        Connection availConn;

        System.out.println("I am in OrcConnection");

            if (connections.size() > 0) {
                availConn = connections.poll();
            } else if (connections.size() < maxConnections) {
                Properties prop = new Properties();
                ResourceBundle resource = ResourceBundle.getBundle("database");
                String url = resource.getString("db.url");
                String user = resource.getString("db.user");
                String pass = resource.getString("db.password");
                prop.put("user", user);
                prop.put("password", pass);
                prop.put("autoReconnect", "true");
                prop.put("characterEncoding", "UTF-8");
                prop.put("useUnicode", "true");
                availConn = DriverManager.getConnection(url,user,pass);
                System.out.println("I am in OrcConnection");
            } else {
                throw new BusyConnections();
            }
            return new ConnWrapper(availConn, this);
    }

    public synchronized void putConnection(Connection conn) {
        if (conn != null) {
            if (connections.size() < maxConnections) {
                connections.add(conn);
            } else {
                try {
                    conn.close();
                } catch (SQLException e) {
                    System.out.println("connection could not be closed" + e.getMessage());
                }
            }
        }
    }


}

【问题讨论】:

  • 我尝试捕获 SQLRecoverableException 并重新建立连接没有成功。
  • 一些选项: 1. 使用 Web 容器为您管理连接(和连接池) 2. 不要尝试重用连接 - 仅在必要时打开,完成后关闭 3.不一定是建议,而是一个选项:使用计时器定期 ping 数据库以避免超时
  • 不要自己写连接池。使用现有的。它并不像你想象的那么简单。
  • @copeg 如何以设定的时间间隔 ping 数据库?我正在为 API 使用 Rest Easy

标签: java oracle jdbc database-connection


【解决方案1】:

我建议你使用 UCP(通用连接池),Oracle 的连接池,可以在here 找到,然后使用Validate When Borrowing 功能。这样,您就可以让 UCP 在需要时测试连接的有效性,并在需要时重新连接。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-29
    • 2011-01-27
    • 2021-07-15
    • 1970-01-01
    • 1970-01-01
    • 2020-04-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多