DeepEdit!

Программирование баз данных на Oracle, техническая документация, литература, статьи и публикации

  • Увеличить размер шрифта
  • Размер шрифта по умолчанию
  • Уменьшить размер шрифта

DBMS_SESSION - Управление сессиями в Oracle Databases

Пакет DBMS_SESSION содержит процедуры, чтобы помочь управлять сеансами, используемыми в качестве части пула соединения.

Идентификатор клиента (SET_IDENTIFIER и CLEAR_IDENTIFIER)

Во многих клиент-серверных приложениях было принято заводить отдельного пользователя базы данных для каждого настоящего пользователя системы. Это делало простым идентификацию и контроль пользователей на уровне базы данных. Если приложения использовали единственного пользователя базы данных и управляли безопасностью внутренне, это делало идентификацию настоящих пользователей трудной задачей. Проблема далее была усложнена использованием многоуровневой архитектурой, которая использовала организацию пула подключений.
Чтобы решать подобные проблемы, Oracle 9iR1 представил процедуры SET_IDENTIFIER и CLEAR_IDENTIFIER, чтобы позволить настоящему пользователю быть связанным с сеансом независимо от того, какой пользователь базы данных использовался для соединения. Процедуры исправляют контент столбца CLIENT_IDENTIFIER в представлении V$SESSION. Когда соединение взято из пула соединения, приложение должно вызвать процедуру SET_IDENTIFIER, передавая реальную информацию о пользователе в качестве параметров.
CONN test/test
EXEC DBMS_SESSION.set_identifier('tim_hall');
COLUMN username FORMAT A20
COLUMN client_identifier FORMAT A20
SELECT USER AS username, SYS_CONTEXT('userenv', 'client_identifier') AS client_identifier FROM dual;
USERNAME CLIENT_IDENTIFIER
-------------------- --------------------
TEST tim_hall
SQL>
Информация видна в представлении V$SESSION когда запрос выполняется от привилегированного пользователя в другом сеансе.
CONN / AS SYSDBA
COLUMN username FORMAT A20
COLUMN client_identifier FORMAT A20
SELECT username, client_identifier FROM v$session WHERE username = 'TEST';
USERNAME CLIENT_IDENTIFIER
-------------------- --------------------
TEST tim_hall
SQL>
Прежде, чем сеанс будет освобожден обратно в пул соединения, приложение должно вызвать процедуру CLEAR_IDENTIFIER.
EXEC DBMS_SESSION.clear_identifier;
SELECT USER AS username, SYS_CONTEXT('userenv', 'client_identifier') AS client_identifier FROM dual;
USERNAME CLIENT_IDENTIFIER
-------------------- --------------------
TEST
SQL>
Столбец CLIENT_IDENTIFIER представления V$SESSION очищен для сеанса.
SELECT username, client_identifier FROM v$session WHERE username = 'TEST';
USERNAME CLIENT_IDENTIFIER
-------------------- --------------------
TEST
SQL>
Более поздние релизы Oracle включают информацию из CLIENT_IDENTIFIER в контрольный журнал, файлы трассировки SQL и инструменты для настройки производительности.

Контекст (CLEAR_CONTEXT и CLEAR_ALL_CONTEXT)

Контексты - это пространства имен, используемые чтобы сохранить пары значение-имя. Хотя контексты были доступны в Oracle 8i, процедура CLEAR_CONTEXT не была представлена до 9iR1, в то время как процедура CLEAR_ALL_CONTEXT была представлена только в 10gR1. Если сеанс был использован как часть пула соединения и состояние его контекстов повторно не были инициализированы, то это могло привести к неожиданному поведению.
CONN / AS SYSDBA
GRANT CREATE ANY CONTEXT TO test;
CONN test/test
-- Create the context.
CREATE OR REPLACE CONTEXT parameter_ctx USING context_api;
-- Create the package to manage the context.
CREATE OR REPLACE PACKAGE context_api AS
PROCEDURE set_parameter(p_name IN VARCHAR2,
p_value IN VARCHAR2);
PROCEDURE clear_context (p_name IN VARCHAR2);
PROCEDURE clear_all_context;
END context_api;
/
CREATE OR REPLACE PACKAGE BODY context_api IS
PROCEDURE set_parameter (p_name IN VARCHAR2,
p_value IN VARCHAR2) IS
BEGIN
DBMS_SESSION.set_context('parameter_ctx', p_name, p_value);
END set_parameter;
PROCEDURE clear_context (p_name IN VARCHAR2) IS
BEGIN
DBMS_SESSION.clear_context('parameter_ctx', attribute => p_name);
END clear_context;
PROCEDURE clear_all_context IS
BEGIN
DBMS_SESSION.clear_all_context('parameter_ctx');
END clear_all_context;
END context_api;
/
-- Set two values in the context and check them.
EXEC context_api.set_parameter('variable1', 'one');
EXEC context_api.set_parameter('variable2', 'two');
COLUMN variable1 FORMAT A20
COLUMN variable2 FORMAT A20
SELECT SYS_CONTEXT('parameter_ctx', 'variable1') AS variable1,
SYS_CONTEXT('parameter_ctx', 'variable2') AS variable2
FROM dual;
VARIABLE1 VARIABLE2
-------------------- --------------------
one two
SQL>
-- Clear one of the name-value pairs and retest.
EXEC context_api.clear_context('variable1');
SELECT SYS_CONTEXT('parameter_ctx', 'variable1') AS variable1,
SYS_CONTEXT('parameter_ctx', 'variable2') AS variable2
FROM dual;
VARIABLE1 VARIABLE2
-------------------- --------------------
two
SQL>
-- Clear all name-value pairs and retest.
EXEC context_api.clear_all_context;
SELECT SYS_CONTEXT('parameter_ctx', 'variable1') AS variable1,
SYS_CONTEXT('parameter_ctx', 'variable2') AS variable2
FROM dual;
VARIABLE1 VARIABLE2
-------------------- --------------------
SQL>
Запрос CLEAR_CONTEXT с параметром ATTRIBUTE устанавливает в NULL, подобно запросу процедуры CLEAR_ALL_CONTEXT.

Пакеты (RESET_PACKAGE)

У сеансов есть возможность изменить состояние пакета, изменяя значения переменных пакета. Если сеанс был использован как часть пула соединения и состояние его контекстов повторно не были инициализированы, то это могло привести к неожиданному поведению. Чтобы решить этe проблему, можно вызвать процедуру RESET_PACKAGE, доступную начиная с Oracle 7для повторной инициализации всех PL/SQL пакетов.
CREATE OR REPLACE PACKAGE p1 AS
FUNCTION get_value RETURN NUMBER;
PROCEDURE set_value (p_value IN NUMBER);
END p1;
/
CREATE OR REPLACE PACKAGE BODY p1 AS
g_number NUMBER := 1;
FUNCTION get_value RETURN NUMBER AS
BEGIN
RETURN g_number;
END get_value;
PROCEDURE set_value (p_value IN NUMBER) AS
BEGIN
g_number := p_value;
END set_value;
END p1;
/
-- Check the current value.
SELECT p1.get_value FROM dual;
GET_VALUE
----------
1
SQL>
-- Alter the value and retest.
EXEC p1.set_value(2);
SELECT p1.get_value FROM dual;
GET_VALUE
----------
2
SQL>
-- Reset the package state and retest.
EXEC DBMS_SESSION.reset_package;
SELECT p1.get_value FROM dual;
GET_VALUE
----------
1
SQL>

Память (FREE_UNUSED_USER_MEMORY)

Если сеанс выполнит операции, которые выделяют большой объем памяти в PGA или UGA, то эта память не будет возвращена до разъединений сеанса. Поскольку сеансы в соединении объединяются в пул, это может представлять проблему, если ими не управляют должным образом. Как понятно из названия, процедура FREE_UNUSED_USER_MEMORY, доступная начиная с Oracle 7, освобождает неиспользованную память в сеансе.
CONN / AS SYSDBA
GRANT SELECT ON v_$mystat TO test;
GRANT SELECT ON v_$statname TO test;
CONN test/test
-- Create a package with a collection as a package variable.
CREATE OR REPLACE PACKAGE p1 AS
FUNCTION get_pga_size RETURN NUMBER;
PROCEDURE populate_tab;
PROCEDURE empty_tab;
END p1;
/
CREATE OR REPLACE PACKAGE BODY p1 AS
TYPE t_tab IS TABLE OF all_objects%ROWTYPE;
g_tab t_tab;
FUNCTION get_pga_size RETURN NUMBER AS
l_number NUMBER;
BEGIN
SELECT ms.value
INTO l_number
FROM v$mystat ms
JOIN v$statname sn ON sn.statistic# = ms.statistic#
WHERE sn.name = 'session pga memory';
RETURN l_number;
END get_pga_size;
PROCEDURE populate_tab AS
BEGIN
SELECT *
BULK COLLECT INTO g_tab
FROM all_objects;
END populate_tab;
PROCEDURE empty_tab AS
BEGIN
g_tab.delete;
END empty_tab;
END p1;
/
-- Check the current PGA size.
SELECT p1.get_pga_size FROM dual;
GET_PGA_SIZE
------------
3416168
SQL>
-- Populate the collection and retest.
EXEC p1.populate_tab;
SELECT p1.get_pga_size FROM dual;
GET_PGA_SIZE
------------
42279016
SQL>
-- Empty the collection and retest.
EXEC p1.empty_tab;
SELECT p1.get_pga_size FROM dual;
GET_PGA_SIZE
------------
42279016
SQL>
-- Free unused memory and retest.
EXEC DBMS_SESSION.reset_package;
SELECT p1.get_pga_size FROM dual;
GET_PGA_SIZE
------------
3285096
SQL>







jAntivirus