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(); } } }
进一步优化建议
- 用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(); } }
- 引入连接池:对于你的Swing项目(有定时器频繁刷新数据),强烈建议用连接池(比如HikariCP、Apache DBCP)。连接池可以复用数据库连接,避免频繁创建/销毁连接的开销,还能自动管理连接数量,从根源上减少泄漏风险。
- 定时器刷新的注意点:定时器每次执行查询时,一定要确保所有数据库资源都被关闭——如果定时器执行频率高,泄漏的速度会非常快,很快又会触发这个错误。
三、紧急恢复方案(暂时无法重启数据库时)
如果现在没法重启数据库,可以先杀掉一些闲置的SYSTEM用户进程临时恢复:
- 查询当前SYSTEM用户的会话:
SELECT sid, serial#, username FROM v$session WHERE username = 'SYSTEM'; - 杀掉闲置的会话(替换
sid和serial#为查询到的值):ALTER SYSTEM KILL SESSION 'sid,serial#';
内容的提问来源于stack exchange,提问作者Navneet
相关产品推荐
相关产品推荐

