You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android JDBC调用connection.close()失效导致PostgreSQL连接数过多问题

问题根因排查

  • 资源关闭逻辑无兜底:当前connection.close()仅写在try代码块末尾,若执行SQL、创建Statement等环节抛出异常,代码会直接跳入catch块,close()逻辑完全不会执行,直接导致连接泄漏。
  • 未完整释放所有JDBC资源:仅关闭了Connection,未同步关闭Statement、ResultSet关联资源,JDBC资源需要按ResultSet → Statement → Connection的顺序释放,上层资源未关闭会导致连接引用被持有无法回收。
  • API调用不符合规范:用executeQuery执行INSERT语句,executeQuery是JDBC专门用于执行SELECT查询的方法,增删改操作需要用executeUpdate,不符合规范的调用会导致PostgreSQL JDBC驱动的资源回收逻辑异常。
  • 成员变量引发并发风险:Connection被定义为类成员变量,若多个线程同时调用insert()方法,新创建的连接会覆盖原有connection变量的引用,导致旧连接的引用丢失,永远无法被关闭。
  • 语法瑕疵:原代码第16行private final String database = "databasename"末尾缺了分号,若功能正常大概率是粘贴时遗漏。

修复方案

使用JDBC 4.1及以上版本支持的try-with-resources语法,无需手动编写关闭逻辑,所有实现AutoCloseable接口的资源会在代码块执行结束后自动释放,同时将Connection改为局部变量避免并发覆盖,替换为正确的DML执行API:

package com.example.testDB;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;

public class Database{

    private final String host = "host";
    private final String database = "databasename";
    private final int port = 1234;
    private final String user = "user";
    private final String pass = "password";
    private final String url = String.format("jdbc:postgresql://%s:%d/%s", host, port, database);
    private boolean status;

    public void insert() {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                String sql = "INSERT INTO TEST_TABLE (COLUMN1, COLUMN2, COLUMN3) VALUES ('TEST','TEST','TEST')";
                // try括号内的资源会自动按顺序关闭,无需手动调用close()
                try (Connection connection = DriverManager.getConnection(url, user, pass);
                     Statement stmt = connection.createStatement()) {
                    Class.forName("org.postgresql.Driver");
                    // 增删改语句使用executeUpdate
                    stmt.executeUpdate(sql);
                    status = true;
                    System.out.println("connected:" + status);
                } catch (Exception e) {
                    status = false;
                    System.out.print(e.getMessage());
                    e.printStackTrace();
                }
            }
        });
        thread.start();
        try {
            thread.join();
        } catch (Exception e) {
            e.printStackTrace();
            this.status = false;
        }
    }
}

额外提示

Android端直接直连PostgreSQL存在严重安全风险,数据库账号密码会直接打包在APK中极易被反编译窃取,生产环境建议改为调用后端服务接口操作数据库。

内容的提问来源于stack exchange,提问作者Igor Lima

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 17:48:03