Application Context是内存中的一组name-value对,application context从属于某个命名空间(namespace)。
用户只能通过一个自定义procedure调用dbms_session.set_context来设置application context的值。用户使用sys_context(<namespace>,<name>)来获取某个application context的值。
Application context分为三种
- dabase session-based application context,又称为local application context。
- global application context
- client session-based application context。通常被OCI使用,存储在客户端内存,而不是Oracle服务器端,也由OCI程序管理。
Global application context存储在SGA中,只要SGA不消亡,global application context就一直存在。global application context常常用于跨会话,与会话无关的场景。dbms_session.set_context有两个默认值为NULL的参数:
- username
- client_id
username = null , client_id=null。所有用户都能访问。
username = null, client_id=<client_id>。 只要session 的client_id =<client_id>,而不管username,都能访问。
username = <database username>, client_id=null。只要session使用指定的oracle schema登陆,不管client_id,都能访问。
username = <database username>, client_id=<client_id>. 常用于statless web session ,如http。
username = <non-database username>, client_id=<client_id> . 该username将用于数据库连接池的owner。
例子1: 所有用户都能访问的application context
CREATE OR REPLACE CONTEXT global_hr_ctx USING hr_ctx_pkg ACCESSED GLOBALLY;
CREATE OR REPLACE PACKAGE hr_ctx_pkg
AS
PROCEDURE set_hr_ctx(sec_level IN VARCHAR2);
PROCEDURE clear_hr_context;
END;
/
CREATE OR REPLACE PACKAGE BODY hr_ctx_pkg
AS
PROCEDURE set_hr_ctx(sec_level IN VARCHAR2)
AS
BEGIN
DBMS_SESSION.SET_CONTEXT(
namespace => 'global_hr_ctx',
attribute => 'job_role',
value => sec_level);
END set_hr_ctx;
PROCEDURE clear_hr_context
AS
BEGIN
DBMS_SESSION.CLEAR_CONTEXT('global_hr_ctx', 'job_role');
END clear_context;
END;
/
例子2: 跨session/application,但是使用同一个数据库schema的application context。
CREATE OR REPLACE PACKAGE hr_ctx_pkg
AS
PROCEDURE set_hr_ctx(sec_level IN VARCHAR2, user_name IN VARCHAR2);
PROCEDURE clear_hr_context;
END;
/
CREATE OR REPLACE PACKAGE BODY hr_ctx_pkg
AS
PROCEDURE set_hr_ctx(sec_level IN VARCHAR2, user_name IN VARCHAR2)
AS
BEGIN
DBMS_SESSION.SET_CONTEXT(
namespace => 'global_hr_ctx',
attribute => 'job_role',
value => sec_level,
username => user_name);
END set_hr_ctx;
PROCEDURE clear_hr_context
AS
BEGIN
DBMS_SESSION.CLEAR_CONTEXT('global_hr_ctx');
END clear_context;
END;
/
两个例子都提供了clear_hr_context 存储过程。这是因为global application context常驻SGA,需要用户使用完毕就清理,以免信息泄露。
USERENV
USERENV是Oracle预定义的命名空间。它包含了许多常用的application context。
- CURRENT_USER
- DB_NAME
- HOST: 客户端机器名
- CLIENT_INFO: 客户端程序用作计数,标识符等