能限制,但只限已认证的数据库会话;SESSIONS_PER_USER控制v$session中同一用户名下ACTIVE或INACTIVE未断开会话总数,不拦TCP连接、监听器排队或密码重试;生效需RESOURCE_LIMIT=TRUE、显式绑定PROFILE且仅约束新会话。

能限制,但只限“已认证的数据库会话”,不是网络连接、不是连接池空闲连接、也不是监听器排队连接。
SESSIONS_PER_USER 是什么,它真能拦住“连不上”吗?
它控制的是同一用户在 v$session 中处于 ACTIVE 或 INACTIVE(但未断开)状态的会话总数。只要用户成功登录并维持一个未 disconnect 的会话,就算一个。
- 不拦 TCP 握手、不拦监听器接受连接、不拦密码输错重试
- 报错是
ORA-02391: exceeded simultaneous SESSIONS_PER_USER limit,出现时说明认证已完成、会话已创建 - 应用用 HikariCP、Druid 这类连接池,若
maxPoolSize=20,而SESSIONS_PER_USER=5,第 6 次获取连接就会失败——因为池里已有 5 个活跃/未关闭会话
为什么设了却没生效?三个最常漏掉的点
配置写了,但实际不起作用,大概率卡在这三步:
-
RESOURCE_LIMIT参数必须为TRUE:查命令SHOW PARAMETER resource_limit;若为FALSE,执行ALTER SYSTEM SET resource_limit = TRUE SCOPE = BOTH - 用户没真正用上这个 profile:查
SELECT username, profile FROM dba_users WHERE username = 'APP_USER',确认返回的是你新建的 profile 名,不是DEFAULT - 已有会话不受影响:限制只对新
CONNECT生效;旧会话仍可继续运行,也不会被自动 kill
怎么设置 + 验证才靠谱?
别跳步,按顺序来:
- 建 profile:
CREATE PROFILE app_limit LIMIT SESSIONS_PER_USER 8; - 赋给用户:
ALTER USER app_user PROFILE app_limit; - 验证 profile 是否生效:
SELECT limit FROM dba_profiles WHERE profile = 'APP_LIMIT' AND resource_name = 'SESSIONS_PER_USER';(应返回8) - 查当前该用户有多少会话:
SELECT COUNT(*) FROM v$session WHERE username = 'APP_USER'; - 手动测试边界:用相同账号连续
sqlplus /@pdb01连接,第 9 次应报ORA-02391
真正容易被绕过或误判的地方,不在 SQL 语法,而在应用侧——比如连接没 close、用了 DBLINK、或用户通过 ALTER SESSION SET CURRENT_SCHEMA 切换 schema 却以为能逃过计数。这些场景下,SESSIONS_PER_USER 依然严格按用户名统计,不会漏,但人容易看错监控指标。


















