_______________________________________________________________________
Las Sesiones de Oracle.
Una sesión no es más que la conexión entre una aplicación X y la Base de Datos Oracle con sus respectivos objetos.
Puede consultar y obtener información de las sesiones de Oracle mediante las vistas V$SESSION y GV$SESSION. Estas vistas contienen entre otros, los campos sid, serial#, inst_id útiles para dropear las secciones.
SELECT
vs.sid
, vs.serial#
, vs.*
FROM sys.v$session vs
;
SELECT
gvs.sid
, gvs.serial#
, gvs.inst_id
, gvs.*
FROM sys.gv$session gvs
;
_______________________________________________________________________
Los Bloqueos de Oracle.
Oracle ofrece varias vistas que permiten consultar los bloqueos de transacciones sobre los distintos objetos de base de datos. Una de ellas es la vista V$LOCK, esta muestras los bloqueos activos en la base de datos sin muchos detalles del objeto bloqueado.
A continuación un ejemplo de la utilidad de la vista V$LOCK:
1. Conectado con HR ejecutamos la consulta:
SELECT
employee_id
, first_name
, last_name
, email
FROM hr.employees
WHERE employee_id = 100
;
2. Actualizamos el campo email, no ejecutamos COMMIT alguno y re ejecutamos la anterior consulta:
UPDATE hr.employees
SET email = email||'@company.com'
WHERE employee_id = 100
;
3. Conectado con un segundo usuario (SYSTEM en mi caso) ejecutamos los mismos script anteriores:
/*Debido a que el usuario HR no ejecutó COMMIT luego del UPDATE, esa transacción está pendiente y ningun otro usuario puede ver los cambios.*/
4. Con el usuario SYSTEM tratamos de actualizar el mismo campo email para el empleado 100 y notamos como la transacción no se completa debido al bloqueo del registro:
5. Ahora conectado con un tercel usuario (SYS en mi caso) ejecutamos la siguiente consulta:
SELECT
(
SELECT s.username
FROM sys.v$session s
WHERE s.sid=bker.sid
) AS usuario_bloqueador,
bker.SID AS sid_bloqueador,
(
SELECT s.username
FROM sys.v$session s
WHERE s.sid=bked.sid
) AS usuario_bloqueado,
bked.SID AS sid_bloqueado
FROM
sys.v$lock bker
JOIN sys.v$lock bked
ON (
bker.id1 = bked.id1
AND bker.id2 = bked.id2
)
WHERE
bker.block = 1
AND bked.request > 0
;
_______________________________________________________________________
La Vista V$LOCKED_OBJECT
La vista V$LOCKED_OBJECT permite ver las transacciones bloqueadas en la Base de Datos con más detalle, permitiendo conocer el objeto bloqueado.
La siguiente consulta muestra las mismas sesiones bloqueadas con el objeto que contiene el bloqueo:
SELECT
o.owner||'.'||o.object_name AS objeto
,o.object_type AS tipo_bojeto
,s.username AS usuario_conexion
,s.sid
,s.serial#
,s.status
, DECODE(s.status, 'INACTIVE', 'BLOQUEADOR', 'ACTIVE', 'BLOQUEDADO', 'DESCONOCIDO') AS DESR_USUARIO
FROM
sys.gv$locked_object bo
JOIN sys.gv$session s
ON ( s.sid = bo.session_id)
JOIN sys.dba_objects o
ON (bo.object_id = o.object_id
AND bo.inst_id = s.inst_id)
;
_______________________________________________________________________
Eliminando Bloqueos de Base Datos
Oracle ofrece varios métodos para desbloquear una transacción. Puede utilizar las sentencias:
ALTER SYSTEM KILL SESSION 'SID, SERIAL#' [IMMEDIATE];
La anterior sentencia revierte las transacciones en curso, libera los bloqueos y recupera parcialmente los recursos utilizados; si no incluimos la clausula IMMEDIATE la sesión es marcada como 'marked for kill' para que ésta se elimine tan pronto como le sea posible, teniendo en cuenta que dicho proceso puede tomar varios minutos en completarse.
ALTER SYSTEM DISCONNECT SESSION 'SID, SERIAL#' [POST_TRANSACTION | IMMEDIATE];
La pasada sentencia es un método alternativo para eliminar transacciones bloqueadas. Mientras que KILL SESSION solicita a la sesión que se auto elimine automáticamente, DISCONNECT SESSION termina el proceso del servidor dedicado. Lo que es igual a terminar el proceso desde el sistema operativo.
La cláusula POST_TRANSACTION espera a que se completen las transacciones en curso para luego desconectar la sesión, la cláusula IMMEDIATE desconecta la sesión y las transacciones en curso se revierten inmediatamente.
Tener pendiente que en la sintaxis [ ] indica que ambas cláusulas son opcionales, pero esto no es así, se deben especificar una o ambas, de lo contrario recibiría un error. Si ambas cláusulas son incluidas IMMEDIATE seria ignorada.
ALTER SYSTEM KILL SESSION '1473, 24750' IMMEDIATE;
ALTER SYSTEM DISCONNECT SESSION '1473, 24750' IMMEDIATE;
/*Las dos sentencias anteriores muestran un ejemplo de como terminar la sesión bloqueadora.*/
DECLARE
CURSOR cur_sessions IS
SELECT
vs.sid
, vs.serial#
FROM sys.v$session vs
WHERE sid <> SYS_CONTEXT('USERENV', 'SID')
;
BEGIN
FOR i IN cur_sessions LOOP
BEGIN
EXECUTE IMMEDIATE 'ALTER SYSTEM KILL SESSION '''||i.sid||', '||i.serial#||''' IMMEDIATE';
EXCEPTION
WHEN OTHERS THEN
BEGIN
EXECUTE IMMEDIATE 'ALTER SYSTEM DISCONNECT SESSION '''||i.sid||', '||i.serial#||''' IMMEDIATE';
EXCEPTION
WHEN OTHERSTHEN
NULL;
END;
END;
END LOOP;
END;
/*El bloque PL/SQL anterior consulta todas las sesiones de base de datos diferentes a la sesión actual y utiliza las sentencias KILL SESSION y DISCONNECT SESSION para eliminarlas o desconectarlas .*/
Fuentes
https://docs.oracle.com/cd/B14099_19/web.1012/b15901/sessions001.htm
https://dbaora.com/kill-session-in-oracle/
https://docs.oracle.com/en/database/oracle/oracle-database/19/refrn/V-LOCK.html
https://oracle-base.com/articles/misc/killing-oracle-sessions