viernes, 28 de febrero de 2020

SESIONES INACTIVAS

ORA-02396
Se puede poner un límite en el tiempo inactivo y continuo de una sesión de la manera siguiente. Antes de empezar, es necesario cambiar resource_limit a true. Si no se hace esto, los límites no se hacen cumplir: 

SQL> alter system set resource_limit = true
  2  /
 
Sistema modificado.
 
SQL> 

Luego debes crear un perfil con un límite en el tiempo de inactividad que se llama idle_time. El valor que empleas es en minutos: 

SQL> create profile idle_time_profile
  2  limit idle_time 1
  3  /
 
Perfil creado.
 
SQL> 

Entonces necesitas un usuario para probar el perfil. Se puede crearlo así: 

SQL> create user idle_time_user
  2  identified by idle_time_user
  3  profile idle_time_profile
  4  /
 
Usuario creado.
 
SQL> grant create session to idle_time_user
  2  /
 
Concesion terminada correctamente.
 
SQL>
 
Para probar el perfil, el usuario nuevo se conecta a la base de datos. Lo hago en rojo porque desde ahora tendré que trabajar en dos sesiónes distintas: 

SQL> conn idle_time_user/idle_time_user
Conectado.
SQL>
 
Luego el usuario sys se conecta a la base de datos para monitorizar la sesión del usuario idle_time_user. Por eso, lo hago en azul en una sesión distinta. El usuario sys sabe que la sesión de idle_time_user no hace nada porque tiene un status de INACTIVE:
 
SQL> conn / as sysdba
Conectado.
SQL> select status from v$session
  2  where username = 'IDLE_TIME_USER'
  3  /
 
STATUS
--------
INACTIVE
 
SQL> exec dbms_lock.sleep(60);
 
Procedimiento PL/SQL terminado correctamente.
 
SQL>

Después de un minuto de inactividad, Oracle podría cerrar la sesión de idle_time_user pero no suele hacerlo inmediatamente:
 
SQL> select status from v$session
  2  where username = 'IDLE_TIME_USER'
  3  /
 
STATUS
--------
INACTIVE
 
SQL> exec dbms_lock.sleep(60);
 
Procedimiento PL/SQL terminado correctamente.
 
SQL>
 
Tras dos minutos, Oracle todavía no se da cuenta de la inactividad de idle_time_user

SQL> select status from v$session
  2  where username = 'IDLE_TIME_USER'
  3  /
 
STATUS
--------
INACTIVE
 
SQL> exec dbms_lock.sleep(60);
 
 
Procedimiento PL/SQL terminado correctamente.
 
SQL>
 
Pero tras 3 minutos, Oracle se da cuenta y cambia el status de idle_time_user a SNIPED: 

SQL> select status from v$session
  2  where username = 'IDLE_TIME_USER'
  3  /
 
STATUS
--------
SNIPED
 
SQL>
 

Y cuando idle_time_user vuelve a su sesión, Oracle le da un error ORA-02396 y le dice de conectarse otra vez a la base de datos antes de continuar: 

SQL> select sysdate from dual;
select sysdate from dual
*
ERROR en linea 1:
ORA-02396: ha excedido el tiempo maximo de
inactividad, vuelva a conectarse
 
SQL>


-------------------------------------------------------

Como se Puede Limitar la Duración de una Sesión Oracle

Tenía que limitar la duración de una sesión Oracle mientras preparaba un entorno nuevo. Así decidí documentar lo que hice. Probé el ejemplo bajo estas líneas en una base de datos Oracle 11.2.0.2.7. Para empezar conecté como SYS y limité CONNECT_TIME a un minuto el el perfil DEFAULT: 

SQL> conn / as sysdba
Conectado.
SQL> alter profile default
  2  limit connect_time 1
  3  /
 
Perfil modificado.

SQL>

Luego cambié RESOURCE_LIMIT a TRUE para hacer cumplir los límites: 

SQL> alter system set resource_limit = true
  2  /
 
Sistema modificado.

SQL>

Creé un usuario con el perfil DEFAULT. Entonces me conecté a la base de datos como este usuario, miré CONNECT_TIME en USER_RESOURCE_LIMITS y comprobé la hora cada diez segundos:

SQL> create user andrew
  2  identified by reid
  3  profile default
  4  /
 
Usuario creado.
 
SQL> grant create session to andrew
  2  /
 
Concesion terminada correctamente.
 
SQL> conn andrew/reid
Conectado.
SQL> select limit from user_resource_limits
  2  where resource_name = 'CONNECT_TIME'
  3  /
 
LIMIT
----------------------------------------
1
 
SQL> select to_char(sysdate,'hh24:mi:ss')
  2  time_now from dual
  3  /
 
TIME_NOW
--------
18:29:42
 
SQL> host sleep 10
 
SQL> select to_char(sysdate,'hh24:mi:ss')
  2  time_now from dual
  3  /
 
TIME_NOW
--------
18:29:52
 
SQL> host sleep 10
 
SQL> select to_char(sysdate,'hh24:mi:ss')
  2  time_now from dual
  3  /
 
TIME_NOW
--------
18:30:02
 
SQL> host sleep 10
 
SQL> select to_char(sysdate,'hh24:mi:ss')
  2  time_now from dual
  3  /
 
TIME_NOW
--------
18:30:12
 
SQL> host sleep 10
 
SQL> select to_char(sysdate,'hh24:mi:ss')
  2  time_now from dual
  3  /
 
TIME_NOW
--------
18:30:22
 
SQL> host sleep 10
 
SQL> select to_char(sysdate,'hh24:mi:ss')
  2  time_now from dual
  3  /
 
TIME_NOW
--------
18:30:32
 
SQL> host sleep 10
Después de un minuto, la consulta siguiente fracasó y la sesión terminó con un ORA-02399:

SQL> select to_char(sysdate,'hh24:mi:ss')
  2  time_now from dual
  3  /
select to_char(sysdate,'hh24:mi:ss')
*
ERROR en linea 1:
ORA-00604: se ha producido un error a nivel 1 de SQL
recursivo
ORA-02399: ha excedido el tiempo maximo de conexion,
desconectando
ORA-02399: ha excedido el tiempo maximo de conexion,
desconectando

SQL>

... y una nueva tentativa a emplear la consulta probó que la sesión no estaba conectada a la base de datos: 

SQL> select to_char(sysdate,'hh24:mi:ss')
  2  time_now from dual
  3  /
select to_char(sysdate,'hh24:mi:ss')
*
ERROR en linea 1:
ORA-01012: no esta conectado
Identificador de Proceso: 6736
Identificador de Sesion: 36 Numero de Serie: 9
 
SQL>

 

No hay comentarios: