SESSIONS_PER_USER 是 Oracle PROFILE 中限制同一用户并发会话数的参数,仅在认证成功后对 v$session 中未断开的 ACTIVE/INACTIVE 会话生效,不控制 TCP 连接、监听器队列或连接池空闲连接;需启用 RESOURCE_LIMIT 才生效,且仅约束新登录会话。
SESSIONS_PER_USER 是什么,它真能限制“并发连接”吗?
不能直接限制网络层或应用层的“并发连接数”,只能限制同一用户在数据库中同时存在的会话(session)数量。oracle 不管你客户端开了多少 tcp 连接、连接池里有多少空闲连接,只看 v$session 里 username 相同且未断开(status 为 active 或 inactive)的行数。
典型错误现象是:应用反复重连报 ORA-02391: exceeded simultaneous SESSIONS_PER_USER limit——这说明认证已成功,会话创建失败,不是监听器或密码问题。
- 它不拦截登录前的握手、失败重试、SQL*Plus 连续敲回车等行为
- DBA 用户或有
RESTRICTED SESSION权限者完全不受限 - 共享服务器模式(Shared Server)下仍按用户计数,但底层调度复用会让监控更难对齐
必须开启 RESOURCE_LIMIT 才生效
SESSIONS_PER_USER 是 PROFILE 的资源限制项,而所有 PROFILE 资源限制都依赖实例级开关 RESOURCE_LIMIT。这个参数默认在某些版本中是 FALSE,导致你配了等于白配。
检查命令:SHOW PARAMETER resource_limit。如果返回 FALSE,执行:
ALTER SYSTEM SET resource_limit = TRUE SCOPE = BOTH;
注意:SCOPE = BOTH 表示立即生效 + 写入 SPFILE 持久化;若只写 MEMORY,重启后失效。
怎么设置并确保它作用到目标用户?
不能直接改用户属性,必须走 PROFILE 中间层。PROFILE 是资源策略容器,用户只是被赋予某个 PROFILE。
- 新建 PROFILE:
CREATE PROFILE app_user_limit LIMIT SESSIONS_PER_USER 5; - 赋给用户:
ALTER USER app_user PROFILE app_user_limit; - 验证是否生效:
SELECT LIMIT FROM DBA_PROFILES WHERE PROFILE = 'APP_USER_LIMIT' AND RESOURCE_NAME = 'SESSIONS_PER_USER'; - 查当前该用户真实会话数:
SELECT COUNT(*) FROM v$session WHERE USERNAME = 'APP_USER';
已有会话不受新限制影响,只约束后续新建会话;修改 PROFILE 的 SESSIONS_PER_USER 值后,也不踢掉现有会话。
为什么设了还是拦不住大量连接?常见漏点
根本矛盾在于:开发/运维说的“连接” ≠ Oracle 看到的“会话”。真实场景里最容易踩坑的是这三类:
- 应用没调
connection.close(),导致v$session里堆满INACTIVE会话,很快占满配额 - 用户没显式指定 PROFILE,走的是
DEFAULTPROFILE —— 它的SESSIONS_PER_USER默认是UNLIMITED - 用了连接池(如 HikariCP、UCP),池子 maxPoolSize 设为 20,但
SESSIONS_PER_USER只设了 5,结果第 6 次获取连接就卡住
上线前务必用相同用户名循环 sqlplus user/pass@db 测试边界;别只信配置,要亲眼看到第 N+1 次确实报 ORA-02391。


















