Lorsqu'un enregistrement est verrouillé dans Oracle, pouvons-nous savoir quel enregistrement est verrouillé?

10

Lorsqu'un enregistrement est verrouillé, pouvons-nous savoir lequel est verrouillé?

Comment puis-je obtenir le Rowid d'enregistrement ou quelque chose d'autre?


Je peux obtenir des informations par ce 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(+) 

J'ai trouvé une méthode sur le Web pour obtenir Rowid en utilisant la fonction DBMS_ROWID.ROWID_CREATE()

Mais cela ne semble pas fonctionner.

iafanda
la source
2
Vous ne pouvez voir que les verrous que certains processus attendent, pas ceux qui sont détenus par une transaction.
a_horse_with_no_name
@a_horse_with_no_name - v $ lock vous montre les verrous détenus par une transaction
Chris Saxon
@ChrisSaxon: Vous avez raison. Je faisais référence au fait que vous ne pouvez pas voir quelles lignes ont été verrouillées - j'aurais dû être plus clair.
a_horse_with_no_name
Oracle (contrairement à d'autres bases de données) n'a pas de structure partagée pour les verrous. Cela rend la base de données évolutive, mais d'autre part, vous ne pouvez pas voir tous les verrous. Les verrous sont stockés directement dans des blocs de base de données. Au moment où quelqu'un se bloque une structure "titulaire-serveur" est créée. Ensuite, vous verrez cette paire V$LOCK.
ibre5041

Réponses:

13

Vous ne pouvez pas vraiment répertorier toutes les lignes qui sont verrouillées par une session. Cependant, une fois qu'une session est bloquée par une autre, vous pouvez trouver quelle session / ligne la bloque.

Oracle ne gère pas de liste de verrous de ligne individuels. Au contraire, les verrous sont enregistrés directement à l'intérieur des lignes elles-mêmes - pensez-y comme une colonne supplémentaire.

Vous pouvez trouver quelle session a acquis un verrou sur un objet via la V$LOCKvue, mais cela ne listera que les informations générales, pas au niveau de la ligne.

Avec cette vue, vous pouvez également trouver si une session est bloquée par une autre. Dans ce cas, si une session est bloquée par une autre session, les informations de ligne s'affichent dans les V$SESSIONinformations.

Vous pouvez récupérer le rowid, construisons un exemple avec 2 sessions:

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 session 2 attend maintenant la session 1. Nous pouvons découvrir la ligne de blocage avec:

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

Pour en savoir plus: une description du processus par Tom Kyte .

Vincent Malgrat
la source
3

Vous pouvez trouver tous les verrous de tables dans une base de données Oracle en exécutant la requête suivante

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
la source