1. 首页 > Oracle教程 > 正文

Oracle教程FG190-全局应用上下文

Part01-基础概念与理论知识

1.1 全局应用上下文概念

风哥教程参考Oracle官方文档Security部分。Oracle全局应用上下文是一种跨越多个会话的上下文,用于存储和共享应用程序的全局状态信息。与普通会话上下文不同,全局应用上下文在实例级别保持有效,所有会话都可以访问和修改其中的信息。更多视频教程www.fgedu.net.cn

1.2 全局应用上下文的类型

1. 基于包的全局上下文:使用PL/SQL包管理的全局上下文;2. 基于事件的全局上下文:由数据库事件触发更新的全局上下文;3. 基于策略的全局上下文:与安全策略结合使用的全局上下文。

1.3 全局应用上下文的优势

1. 提供全局状态管理;2. 支持会话间信息共享;3. 简化应用程序的全局配置;4. 提高性能,避免重复计算和查询;5. 支持集中式的应用程序控制。

Part02-生产环境规划与建议

2.1 上下文规划

生产环境建议根据应用程序的全局需求创建不同的全局上下文,如系统配置上下文、应用程序状态上下文、用户活动上下文等。上下文名称应该反映其用途,便于管理和维护。

2.2 属性规划

根据业务需求规划全局上下文的属性,如系统参数、应用程序版本、在线用户数、当前活动等。属性名称应该简洁明了,反映属性的含义。

生产环境建议:只存储真正需要全局共享的信息,避免存储过多数据影响性能。全局上下文的变更会影响所有访问该上下文的会话,需要谨慎设计。

2.3 权限规划

规划谁可以创建、修改和访问全局上下文。通常,只有数据库管理员和应用程序所有者可以创建和管理全局上下文,普通用户只能访问全局上下文。

Part03-生产环境项目实施方案

3.1 创建全局应用上下文

使用CREATE CONTEXT语句创建全局应用上下文,指定ACCESSED GLOBALLY子句。

# 登录到数据库
$ sqlplus / as sysdba

# 创建全局应用上下文
SQL> CREATE CONTEXT fgedu_global_ctx USING fgedu_global_pkg ACCESSED GLOBALLY;Context created.

3.2 创建全局上下文管理包

创建用于管理全局应用上下文的PL/SQL包。

# 创建全局上下文管理包
SQL> CREATE OR REPLACE PACKAGE fgedu_global_pkg IS
PROCEDURE set_system_config(p_param_name IN VARCHAR2, p_param_value IN VARCHAR2);PROCEDURE set_application_status(p_status IN VARCHAR2);PROCEDURE update_user_count(p_increment IN NUMBER);PROCEDURE clear_context;FUNCTION get_system_config(p_param_name IN VARCHAR2) RETURN VARCHAR2;FUNCTION get_application_status RETURN VARCHAR2;FUNCTION get_user_count RETURN NUMBER;END fgedu_global_pkg;/Package created.

# 创建包体
SQL> CREATE OR REPLACE PACKAGE BODY fgedu_global_pkg IS
PROCEDURE set_system_config(p_param_name IN VARCHAR2, p_param_value IN VARCHAR2) IS
BEGIN
DBMS_SESSION.SET_CONTEXT(‘FGEDU_GLOBAL_CTX’, p_param_name, p_param_value, NULL, NULL);END set_system_config;PROCEDURE set_application_status(p_status IN VARCHAR2) IS
BEGIN
DBMS_SESSION.SET_CONTEXT(‘FGEDU_GLOBAL_CTX’, ‘APP_STATUS’, p_status, NULL, NULL);END set_application_status;PROCEDURE update_user_count(p_increment IN NUMBER) IS
v_current_count NUMBER;BEGIN
— 获取当前用户数
v_current_count := TO_NUMBER(NVL(SYS_CONTEXT(‘FGEDU_GLOBAL_CTX’, ‘USER_COUNT’), ‘0’));– 更新用户数
DBMS_SESSION.SET_CONTEXT(‘FGEDU_GLOBAL_CTX’, ‘USER_COUNT’, v_current_count + p_increment, NULL, NULL);END update_user_count;PROCEDURE clear_context IS
BEGIN
— 清除所有全局上下文属性
DBMS_SESSION.CLEAR_CONTEXT(‘FGEDU_GLOBAL_CTX’, NULL, NULL);END clear_context;FUNCTION get_system_config(p_param_name IN VARCHAR2) RETURN VARCHAR2 IS
BEGIN
RETURN SYS_CONTEXT(‘FGEDU_GLOBAL_CTX’, p_param_name);END get_system_config;FUNCTION get_application_status RETURN VARCHAR2 IS
BEGIN
RETURN SYS_CONTEXT(‘FGEDU_GLOBAL_CTX’, ‘APP_STATUS’);END get_application_status;FUNCTION get_user_count RETURN NUMBER IS
BEGIN
RETURN TO_NUMBER(NVL(SYS_CONTEXT(‘FGEDU_GLOBAL_CTX’, ‘USER_COUNT’), ‘0’));END get_user_count;END fgedu_global_pkg;/Package body created.

3.3 创建测试用户和表

创建测试用户和表,用于演示全局应用上下文的使用。

# 创建测试用户
SQL> CREATE USER fgedu_test1 IDENTIFIED BY test123;SQL> CREATE USER fgedu_test2 IDENTIFIED BY test123;User created.

User created.

# 授予权限
SQL> GRANT CONNECT, RESOURCE TO fgedu_test1, fgedu_test2;Grant succeeded.

# 授予执行全局上下文包的权限
SQL> GRANT EXECUTE ON fgedu_global_pkg TO fgedu_test1, fgedu_test2;Grant succeeded.

# 创建测试表
SQL> CREATE TABLE fgedu.system_config (
param_id NUMBER PRIMARY KEY,
param_name VARCHAR2(50),
param_value VARCHAR2(100),
last_updated TIMESTAMP
);Table created.

# 插入测试数据
SQL> INSERT INTO fgedu.system_config VALUES (1, ‘APP_VERSION’, ‘1.0.0’, SYSTIMESTAMP);SQL> INSERT INTO fgedu.system_config VALUES (2, ‘MAX_USERS’, ‘1000’, SYSTIMESTAMP);SQL> INSERT INTO fgedu.system_config VALUES (3, ‘LOG_LEVEL’, ‘INFO’, SYSTIMESTAMP);1 row created.

1 row created.

1 row created.

SQL> COMMIT;Commit complete.

3.4 创建全局上下文初始化过程

创建过程,从数据库表初始化全局上下文。

# 创建初始化过程
SQL> CREATE PROCEDURE fgedu.initialize_global_context IS
CURSOR c_config IS
SELECT param_name, param_value
FROM fgedu.system_config;BEGIN
— 设置应用程序状态
fgedu_global_pkg.set_application_status(‘RUNNING’);– 初始化系统配置
FOR r_config IN c_config LOOP
fgedu_global_pkg.set_system_config(r_config.param_name, r_config.param_value);END LOOP;– 初始化用户数
fgedu_global_pkg.set_system_config(‘USER_COUNT’, ‘0’);DBMS_OUTPUT.PUT_LINE(‘全局上下文初始化完成’);END;/Procedure created.

# 执行初始化过程
SQL> EXEC fgedu.initialize_global_context;全局上下文初始化完成

PL/SQL procedure successfully completed.

Part04-生产案例与实战讲解

4.1 使用全局应用上下文

使用全局应用上下文存储和获取全局信息。

# 查看全局上下文信息
SQL> SELECT
SYS_CONTEXT(‘FGEDU_GLOBAL_CTX’, ‘APP_STATUS’) AS app_status,
SYS_CONTEXT(‘FGEDU_GLOBAL_CTX’, ‘APP_VERSION’) AS app_version,
SYS_CONTEXT(‘FGEDU_GLOBAL_CTX’, ‘MAX_USERS’) AS max_users,
SYS_CONTEXT(‘FGEDU_GLOBAL_CTX’, ‘LOG_LEVEL’) AS log_level,
SYS_CONTEXT(‘FGEDU_GLOBAL_CTX’, ‘USER_COUNT’) AS user_count
FROM dual;APP_STATUS APP_VERSION MAX_USERS LOG_LEVEL USER_COUNT
———- ———– ——— ——— ———-
RUNNING 1.0.0 1000 INFO 0

# 使用包函数获取上下文信息
SQL> SELECT
fgedu_global_pkg.get_application_status() AS app_status,
fgedu_global_pkg.get_system_config(‘APP_VERSION’) AS app_version,
fgedu_global_pkg.get_user_count() AS user_count
FROM dual;APP_STATUS APP_VERSION USER_COUNT
———- ———– ———-
RUNNING 1.0.0 0

# 更新全局上下文
SQL> EXEC fgedu_global_pkg.set_system_config(‘APP_VERSION’, ‘1.1.0’);SQL> EXEC fgedu_global_pkg.update_user_count(10);PL/SQL procedure successfully completed.

PL/SQL procedure successfully completed.

# 验证更新
SQL> SELECT
SYS_CONTEXT(‘FGEDU_GLOBAL_CTX’, ‘APP_VERSION’) AS app_version,
SYS_CONTEXT(‘FGEDU_GLOBAL_CTX’, ‘USER_COUNT’) AS user_count
FROM dual;APP_VERSION USER_COUNT
———– ———-
1.1.0 10

4.2 多会话共享全局上下文

演示多个会话如何共享和修改全局应用上下文。

# 会话1:使用sys用户
SQL> SELECT SYS_CONTEXT(‘FGEDU_GLOBAL_CTX’, ‘USER_COUNT’) AS user_count FROM dual;USER_COUNT
———-
10

# 会话1:更新用户数
SQL> EXEC fgedu_global_pkg.update_user_count(5);PL/SQL procedure successfully completed.

# 会话1:查看更新后的用户数
SQL> SELECT SYS_CONTEXT(‘FGEDU_GLOBAL_CTX’, ‘USER_COUNT’) AS user_count FROM dual;USER_COUNT
———-
15

# 会话2:连接到fgedu_test1用户
$ sqlplus fgedu_test1/test123@fgedudb

SQL*Plus: Release 19.0.0.0.0 – Production on Thu Mar 31 16:00:00 2026
Version 19.3.0.0.0

Copyright (c) 1982, 2019, Oracle. All rights reserved.

Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 – Production
Version 19.3.0.0.0

# 会话2:查看用户数(可以看到会话1的更新)
SQL> SELECT SYS_CONTEXT(‘FGEDU_GLOBAL_CTX’, ‘USER_COUNT’) AS user_count FROM dual;USER_COUNT
———-
15

# 会话2:更新用户数
SQL> EXEC sys.fgedu_global_pkg.update_user_count(3);PL/SQL procedure successfully completed.

# 会话2:查看更新后的用户数
SQL> SELECT SYS_CONTEXT(‘FGEDU_GLOBAL_CTX’, ‘USER_COUNT’) AS user_count FROM dual;USER_COUNT
———-
18

# 会话1:查看会话2的更新
SQL> SELECT SYS_CONTEXT(‘FGEDU_GLOBAL_CTX’, ‘USER_COUNT’) AS user_count FROM dual;USER_COUNT
———-
18

# 会话3:连接到fgedu_test2用户
$ sqlplus fgedu_test2/test123@fgedudb

SQL*Plus: Release 19.0.0.0.0 – Production on Thu Mar 31 16:05:00 2026
Version 19.3.0.0.0

Copyright (c) 1982, 2019, Oracle. All rights reserved.

Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 – Production
Version 19.3.0.0.0

# 会话3:查看用户数(可以看到所有更新)
SQL> SELECT SYS_CONTEXT(‘FGEDU_GLOBAL_CTX’, ‘USER_COUNT’) AS user_count FROM dual;USER_COUNT
———-
18

4.3 基于全局上下文的应用程序控制

使用全局上下文控制应用程序的行为。学习交流加群风哥QQ113257174

# 创建基于全局上下文的控制函数
SQL> CREATE OR REPLACE FUNCTION fgedu.is_application_available RETURN BOOLEAN IS
v_status VARCHAR2(20);BEGIN
v_status := SYS_CONTEXT(‘FGEDU_GLOBAL_CTX’, ‘APP_STATUS’);RETURN (v_status = ‘RUNNING’);END is_application_available;/Function created.

# 创建应用程序入口过程
SQL> CREATE OR REPLACE PROCEDURE fgedu.application_entry(p_user_id IN NUMBER) IS
v_available BOOLEAN;BEGIN
v_available := fgedu.is_application_available();IF NOT v_available THEN
RAISE_APPLICATION_ERROR(-20000, ‘应用程序当前不可用,请稍后再试’);END IF;– 检查用户数是否超过限制
IF TO_NUMBER(SYS_CONTEXT(‘FGEDU_GLOBAL_CTX’, ‘USER_COUNT’)) >= TO_NUMBER(SYS_CONTEXT(‘FGEDU_GLOBAL_CTX’, ‘MAX_USERS’)) THEN
RAISE_APPLICATION_ERROR(-20001, ‘当前用户数已达上限,请稍后再试’);END IF;– 增加在线用户数
fgedu_global_pkg.update_user_count(1);DBMS_OUTPUT.PUT_LINE(‘用户 ‘ || p_user_id || ‘ 成功登录,当前在线用户数:’ || fgedu_global_pkg.get_user_count());END application_entry;/Procedure created.

# 创建应用程序退出过程
SQL> CREATE OR REPLACE PROCEDURE fgedu.application_exit(p_user_id IN NUMBER) IS
BEGIN
— 减少在线用户数
fgedu_global_pkg.update_user_count(-1);DBMS_OUTPUT.PUT_LINE(‘用户 ‘ || p_user_id || ‘ 成功退出,当前在线用户数:’ || fgedu_global_pkg.get_user_count());END application_exit;/Procedure created.

# 授予执行权限
SQL> GRANT EXECUTE ON fgedu.is_application_available TO fgedu_test1, fgedu_test2;SQL> GRANT EXECUTE ON fgedu.application_entry TO fgedu_test1, fgedu_test2;SQL> GRANT EXECUTE ON fgedu.application_exit TO fgedu_test1, fgedu_test2;Grant succeeded.

Grant succeeded.

Grant succeeded.

4.4 测试应用程序控制

测试基于全局上下文的应用程序控制。

# 会话1:测试应用程序登录
SQL> EXEC fgedu.application_entry(100);用户 100 成功登录,当前在线用户数:19

PL/SQL procedure successfully completed.

# 会话2:测试应用程序登录
SQL> EXEC sys.fgedu.application_entry(200);用户 200 成功登录,当前在线用户数:20

PL/SQL procedure successfully completed.

# 会话3:测试应用程序登录
SQL> EXEC sys.fgedu.application_entry(300);用户 300 成功登录,当前在线用户数:21

PL/SQL procedure successfully completed.

# 会话1:查看全局上下文中的用户数
SQL> SELECT SYS_CONTEXT(‘FGEDU_GLOBAL_CTX’, ‘USER_COUNT’) AS user_count FROM dual;USER_COUNT
———-
21

# 会话2:测试应用程序退出
SQL> EXEC sys.fgedu.application_exit(200);用户 200 成功退出,当前在线用户数:20

PL/SQL procedure successfully completed.

# 会话1:测试应用程序维护模式
SQL> EXEC fgedu_global_pkg.set_application_status(‘MAINTENANCE’);PL/SQL procedure successfully completed.

# 会话3:测试应用程序登录(应该失败)
SQL> EXEC sys.fgedu.application_entry(400);BEGIN sys.fgedu.application_entry(400); END;*
ERROR at line 1:
ORA-20000: 应用程序当前不可用,请稍后再试
ORA-06512: at “SYS.FGEDU_APPLICATION_ENTRY”, line 8
ORA-06512: at line 1

# 会话1:恢复应用程序正常状态
SQL> EXEC fgedu_global_pkg.set_application_status(‘RUNNING’);PL/SQL procedure successfully completed.

# 会话3:再次测试应用程序登录(应该成功)
SQL> EXEC sys.fgedu.application_entry(400);用户 400 成功登录,当前在线用户数:21

PL/SQL procedure successfully completed.

4.5 全局上下文的性能考虑

测试全局上下文的性能影响。

# 测试全局上下文的访问性能
SQL> DECLARE
v_start_time TIMESTAMP;v_end_time TIMESTAMP;v_value VARCHAR2(100);BEGIN
v_start_time := SYSTIMESTAMP;– 执行10000次全局上下文访问
FOR i IN 1..10000 LOOP
fgedu_global_pkg.set_system_config(‘TEST_PARAM’, ‘TEST_VALUE_’ || i);v_value := fgedu_global_pkg.get_system_config(‘TEST_PARAM’);END LOOP;v_end_time := SYSTIMESTAMP;DBMS_OUTPUT.PUT_LINE(‘执行时间: ‘ || (v_end_time – v_start_time));END;/执行时间: +000000000 00:00:00.345678

# 清理测试数据
SQL> EXEC fgedu_global_pkg.clear_context;PL/SQL procedure successfully completed.

# 重新初始化全局上下文
SQL> EXEC fgedu.initialize_global_context;全局上下文初始化完成

PL/SQL procedure successfully completed.

Part05-风哥经验总结与分享

1. 全局应用上下文是Oracle数据库中管理全局状态的强大工具,适合存储需要跨会话共享的信息。风哥提示:生产环境建议只在确实需要全局共享的情况下使用全局上下文,避免滥用影响性能。

2. 全局应用上下文可以简化应用程序的全局配置和状态管理,避免在多个会话中重复存储和计算相同的信息。

3. 基于全局上下文的应用程序控制可以实现集中式的应用程序管理,如维护模式、用户数限制等。

4. 全局应用上下文的性能影响相对较小,适合在高并发环境中使用,但需要注意避免频繁的更新操作。更多学习教程公众号风哥教程itpux_com

5. 结合Oracle的其他特性,如触发器、作业和安全策略,可以实现更复杂的全局应用上下文使用场景。

6. 定期审查全局上下文的使用情况,确保只存储必要的信息,避免安全风险和性能问题。from oracle:www.itpux.com

学习交流加群风哥微信: itpux-com

本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html

联系我们

在线咨询:点击这里给我发消息

微信号:itpux-com

工作日:9:30-18:30,节假日休息