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

Java 8 Swing项目连接Oracle 10g遇ORA-12519错误求解决方案

解决 ORA-12519: TNS:no appropriate service handler found 错误

我来帮你一步步搞定这个问题,这个错误本质是数据库的可用进程被耗尽,结合你的描述和代码来看,主要有两个核心问题需要处理:

一、先搞定processes参数不生效的问题

你已经执行了alter system set processes=300 scope=spfile;但参数还是40,这是因为scope=spfile只会修改Oracle的初始化参数文件,不会立即生效——必须重启数据库才能让新参数生效。具体步骤:

  • 登录到数据库服务器,用sysdba身份执行:
    shutdown immediate;
    startup;
    
  • 重启后验证参数:执行show parameter processes;或者你之前用的资源查询语句,确认LIMIT_VALUE已经变成300。

二、修复代码里的连接泄漏(这才是根源!)

你的代码存在严重的数据库资源泄漏——每次调用GetData或UpdateData都会新建Connection、Statement,但用完之后完全没关闭这些资源!这就导致每个数据库连接一直占用着进程,很快就把40个进程名额耗光了。哪怕你把processes调到300,不修复这个问题迟早还是会耗尽。

修复后的代码示例(遵循Java规范+资源安全)

package connection;
import java.sql.*;

// 类名首字母大写,符合Java编码规范
public class Conn {
    // 不要把Connection/Statement/ResultSet作为类成员,每次方法内创建并及时关闭
    public ResultSet getData(String sql) {
        Connection con = null;
        Statement st = null;
        ResultSet rs = null;
        try {
            Class.forName("oracle.jdbc.OracleDriver");
            con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "system", "123456");
            st = con.createStatement();
            rs = st.executeQuery(sql);
        } catch (Exception e) {
            e.printStackTrace(); // 别只打印异常对象,打印堆栈能帮你定位具体出错位置
            // 发生异常时,关闭已经创建的资源
            closeResources(rs, st, con);
        }
        return rs;
        // 注意:返回ResultSet的话,调用方用完后必须手动关闭所有资源!
        // 更推荐的做法是把查询结果转成List等内存对象,直接关闭连接,避免持有ResultSet
    }

    public void updateData(String sql) {
        Connection con = null;
        Statement st = null;
        try {
            Class.forName("oracle.jdbc.OracleDriver");
            con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE", "system", "123456");
            st = con.createStatement();
            st.executeUpdate(sql);
            System.out.println("Record Updated...");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 不管操作成功还是失败,都必须关闭资源!
            closeResources(null, st, con);
        }
    }

    // 封装一个统一关闭资源的工具方法,避免重复代码
    private void closeResources(ResultSet rs, Statement st, Connection con) {
        // 按ResultSet→Statement→Connection的顺序关闭,避免依赖问题
        try {
            if (rs != null) rs.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if (st != null) st.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if (con != null) con.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

进一步优化建议

  1. 用try-with-resources简化资源管理:Java 7+支持这个语法,能自动关闭实现AutoCloseable接口的资源(Connection、Statement、ResultSet都符合),代码更简洁且不会漏关:
public void updateData(String sql) {
    try (
        // 在这里声明的资源,try块结束后会自动关闭
        Connection con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE", "system", "123456");
        Statement st = con.createStatement()
    ) {
        Class.forName("oracle.jdbc.OracleDriver");
        st.executeUpdate(sql);
        System.out.println("Record Updated...");
    } catch (Exception e) {
        e.printStackTrace();
    }
}
  1. 引入连接池:对于你的Swing项目(有定时器频繁刷新数据),强烈建议用连接池(比如HikariCP、Apache DBCP)。连接池可以复用数据库连接,避免频繁创建/销毁连接的开销,还能自动管理连接数量,从根源上减少泄漏风险。
  2. 定时器刷新的注意点:定时器每次执行查询时,一定要确保所有数据库资源都被关闭——如果定时器执行频率高,泄漏的速度会非常快,很快又会触发这个错误。

三、紧急恢复方案(暂时无法重启数据库时)

如果现在没法重启数据库,可以先杀掉一些闲置的SYSTEM用户进程临时恢复:

  • 查询当前SYSTEM用户的会话:
    SELECT sid, serial#, username FROM v$session WHERE username = 'SYSTEM';
    
  • 杀掉闲置的会话(替换sid和serial#为查询到的值):
    ALTER SYSTEM KILL SESSION 'sid,serial#';
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:24:03