Resource Manager不能限制并发会话数,唯一可靠方式是PROFILE配合SESSIONS_PER_USER参数,并确保RESOURCE_LIMIT=TRUE、用户显式绑定该PROFILE;它统计ACTIVE/INACTIVE会话,不适用于TCP连接或连接池空闲连接。
RESOURCE_MANAGER 不能限制并发会话数,别配错了
oracle 的 resource manager(资源管理器)**不提供任何控制用户并发会话数量的机制**。它只管 cpu、io、并行度、执行时间等运行时资源调度,sessions_per_user 是 profile 的专属参数,resource manager 根本没有对应字段或指令。如果你在 dba_rsrc_plan_directives 里翻找类似 session_limit 或 max_sessions 的配置项,注定找不到——它不存在。
真正限制并发数只能靠 PROFILE + RESOURCE_LIMIT
限制单个用户最大并发数据库会话(即已认证、状态非 KILLED 的 v$session 行数),唯一可靠路径是:
-
ALTER SYSTEM SET resource_limit = TRUE SCOPE=BOTH—— 必须开启,否则所有 PROFILE 资源限制(包括SESSIONS_PER_USER)全部失效 -
CREATE PROFILE app_limit LIMIT SESSIONS_PER_USER 10—— 数值按应用连接池最大活跃数预估,别盲目设 1 或 100 -
ALTER USER app_user PROFILE app_limit—— 用户必须显式绑定该 PROFILE;走默认DEFAULTPROFILE 的话,SESSIONS_PER_USER是UNLIMITED
注意:SESSIONS_PER_USER 统计的是同一用户名下所有 STATUS IN ('ACTIVE', 'INACTIVE') 的会话,不管 SERVICE_NAME 或客户端 IP 是否不同。连接池没正确 close() 导致大量 INACTIVE 残留,就会提前触发 ORA-02391。
为什么你改了 PROFILE 还是不限制?检查这三点
常见“配置了但没生效”,基本卡在这几个地方:
- 查
SHOW PARAMETER resource_limit—— 返回FALSE?立刻补ALTER SYSTEM SET resource_limit = TRUE - 查
SELECT PROFILE FROM DBA_USERS WHERE USERNAME = 'APP_USER'—— 不是APP_LIMIT?说明ALTER USER没执行或执行错用户 - 查
SELECT COUNT(*) FROM v$session WHERE USERNAME = 'APP_USER'—— 如果远低于你设的 10 却已报ORA-02391,大概率有同名 schema 切换(如ALTER SESSION SET CURRENT_SCHEMA)或 DBLINK 会话被计入
想动态控并发?Resource Manager 不行,得换思路
PROFILE 的 SESSIONS_PER_USER 是硬限制,但它是静态的、会话级的,无法按时间段、客户端 IP、服务名做差异化控制,也不能自动 kill 超限会话。真要动态干预,只能绕开数据库原生机制:
- 用登录触发器(
LOGONtrigger)查v$session实时计数,超限时RAISE_APPLICATION_ERROR拒绝新会话(注意:触发器本身也占一个会话,需预留余量) - 在应用层连接池(如 HikariCP)配置
maximumPoolSize,并与SESSIONS_PER_USER值对齐,避免池内空闲连接耗尽配额 - 定期跑清理脚本:杀掉长时间
INACTIVE且LAST_CALL_ET > 3600的会话(慎用,需排除合法长事务)
Resource Manager 再强大,也管不了会话数量这件事。把并发数和 CPU/IO 混在一起配,是多数人上线前最常踩的逻辑坑。


















