Cuando un registro está bloqueado en Oracle, ¿podemos saber qué registro está bloqueado?

10

Cuando un registro está bloqueado, ¿podemos saber cuál está bloqueado?

¿Cómo puedo obtener el registro rowid o alguna otra información?


Puedo obtener información de este sql

SELECT c.ROW_WAIT_OBJ#,c.ROW_WAIT_FILE#,c.ROW_WAIT_BLOCK#,c.ROW_WAIT_ROW#
   FROM v$locked_object a, dba_objects b, v$session c    
WHERE a.object_id = b.object_id    
    AND a.SESSION_ID = c.sid(+) 

Encontré un método en la web para obtener rowid usando la función DBMS_ROWID.ROWID_CREATE()

Pero no parece funcionar.

iafanda
fuente
2
Solo puede ver bloqueos que algún proceso está esperando, no aquellos que están retenidos por una transacción.
a_horse_with_no_name
@a_horse_with_no_name - v $ lock le muestra los bloqueos en poder de una transacción
Chris Saxon
@ ChrisSaxon: Tienes razón. Me refería al hecho de que no puedes ver qué filas se han bloqueado, debería haber sido más claro.
a_horse_with_no_name
Oracle (al contrario de otras bases de datos) no tiene ninguna estructura compartida para los bloqueos. Esto hace que la base de datos sea escalable, pero por otro lado no puede ver todos los bloqueos. Los bloqueos se almacenan en bloques de bases de datos directamente. En el momento en que alguien se bloquea, se crea una estructura "titular-camarero". Entonces verá este par en V$LOCK.
ibre5041

Respuestas:

13

Realmente no puede enumerar todas las filas que están bloqueadas por una sesión. Sin embargo, una vez que otra sesión está bloqueando una sesión , puede encontrar qué sesión / fila la está bloqueando.

Oracle no mantiene una lista de bloqueos de fila individuales. Por el contrario, los bloqueos se registran directamente dentro de las propias filas; piense en ello como una columna adicional.

Puede encontrar qué sesión ha adquirido un bloqueo en un objeto a través de la V$LOCKvista, pero esto solo mostrará información general, no a nivel de fila.

Con esta vista también puede encontrar si una sesión está siendo bloqueada por otra. En ese caso, si otra sesión bloquea una sesión, la información de la fila se muestra en la V$SESSIONinformación.

Puede recuperar el rowid, construyamos un ejemplo con 2 sesiones:

SESSION1> create table test as select * from all_objects;

Table created

SESSION1> select rowid from test where object_name = 'TEST' for update;

ROWID
------------------
AAMnFEAAaAAALTDAAz

/* setting identifiers to help with identifying this session later */
SESSION2> exec dbms_application_info.set_client_info('012345');

PL/SQL procedure successfully completed

SESSION2> select 1 from test where object_name = 'TEST' for update;
/*  this will block */

La sesión 2 ahora está esperando la sesión 1. Podemos descubrir la fila de bloqueo con:

SESSION1> SELECT o.object_name,
       2         dbms_rowid.ROWID_CREATE (1,
       3                                  s.ROW_WAIT_OBJ#,
       4                                  s.ROW_WAIT_FILE#,
       5                                  s.ROW_WAIT_BLOCK#,
       6                                  s.ROW_WAIT_ROW#) rid
       7     FROM dba_objects o, v$session s
       8    WHERE o.object_id = s.row_wait_obj#
       9      AND s.client_info = '012345';

OBJECT_NAME     RID
--------------- ------------------
TEST            AAMnFEAAaAAALTDAAz

Para leer más: una descripción del proceso por Tom Kyte .

Vincent Malgrat
fuente
3

Puede encontrar todos los bloqueos de tablas en una base de datos Oracle ejecutando la siguiente consulta

select
   c.owner,
   c.object_name,
   c.object_type,
   b.sid,
   b.serial#,
   b.status,
   b.osuser,
   b.machine
from
   v$locked_object a ,
   v$session b,
   dba_objects c
where
   b.sid = a.session_id
and
   a.object_id = c.object_id;
Baji Shaik
fuente