最直接的方式是查询V$SESSION视图统计会话数,需授权SELECT ON SYS.V_$SESSION,推荐条件为USERNAME IS NOT NULL AND TYPE = 'USER' AND (STATUS = 'ACTIVE' OR STATUS = 'INACTIVE'),并定期轮询以反映动态变化。

查 V$SESSION 是最直接的方式
Oracle 没有内置的“活动连接数”全局计数器,必须从动态性能视图中聚合统计。核心就是查 V$SESSION,它实时反映每个会话状态。注意:普通用户默认无权访问该视图,需 DBA 授予 SELECT_CATALOG_ROLE 或显式授权:
GRANT SELECT ON SYS.V_$SESSION TO your_user;
(注意是 V_$SESSION,带下划线,不是 V$SESSION —— 视图同义词在 SYS 下才映射正确)
Java 里用 JDBC 执行 COUNT 查询即可
不需要复杂框架,一条 SQL + 标准 JDBC 就够了。关键点在于过滤条件是否准确:
-
STATUS = 'ACTIVE'只统计当前正在执行 SQL 的会话,但会漏掉空闲但未断开的连接(比如连接池维持的 idle 连接) - 更贴近“活跃连接池占用”的实际需求,建议用:
STATUS = 'ACTIVE' OR STATUS = 'INACTIVE'并加上USERNAME IS NOT NULL(排除后台进程) - 如果想排除 Oracle 自身后台进程(如
DBW0,LGWR),再加TYPE = 'USER'
示例查询语句:
SELECT COUNT(*) FROM V$SESSION WHERE USERNAME IS NOT NULL AND TYPE = 'USER' AND (STATUS = 'ACTIVE' OR STATUS = 'INACTIVE');
注意连接权限和时序问题
Java 程序用的数据库账号,必须能稳定执行上述查询,否则会抛 java.sql.SQLException: ORA-00942: table or view does not exist。这不是代码写错了,是权限没给够。
- 不要在应用启动时只查一次就缓存结果——连接数是动态变化的,必须定期轮询(比如每 10 秒)
- 避免在高并发场景下频繁查
V$SESSION,它本身有一定开销;若只需趋势监控,可考虑改用V$PROCESS或结合 AWR 报表做采样 - Oracle 12c+ 支持
CDB$VIEW,如果是多租户环境,需确认是否要查CDB$VIEW版本或指定CON_ID
别把 JDBC 连接数和数据库会话数混为一谈
Java 应用层的 DataSource 连接池大小(如 HikariCP 的 maximumPoolSize)只是上限,不等于当前真实占用的数据库会话数。真正压到 Oracle 的,是已调用 connection.createStatement() 且尚未 close 的那些会话。
- 常见误判:看到连接池用了 20/50,就认为 Oracle 里有 20 个会话——错。可能其中 15 个只是 idle 在池里,对应
STATUS = 'INACTIVE';也可能有 5 个正执行慢 SQL,卡在STATUS = 'ACTIVE' - 排查连接泄漏时,应比对 Java 层
getConnection()/close()日志 和 数据库侧V$SESSION中LOGON_TIME较老但STATUS = 'INACTIVE'的会话
真正难的不是查数字,而是把 Java 连接生命周期、Oracle 会话状态、网络中断恢复逻辑这三层对齐。漏掉任意一层,监控值就失去意义。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











