Können wir wissen, welcher Datensatz gesperrt ist, wenn ein Datensatz in Oracle gesperrt ist?

10

Können wir wissen, welcher Datensatz gesperrt ist, wenn ein Datensatz gesperrt ist?

Wie kann ich die Datensatz-Rowid oder andere Informationen erhalten?


Ich kann einige Informationen von diesem SQL bekommen

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(+) 

Ich habe im Web eine Methode gefunden, um mithilfe der Funktion eine Rowid zu erhalten DBMS_ROWID.ROWID_CREATE()

Aber es scheint nicht zu funktionieren.

iafanda
quelle
2
Sie können nur Sperren sehen, auf die ein Prozess wartet, nicht diejenigen, die von einer Transaktion gehalten werden.
a_horse_with_no_name
@a_horse_with_no_name - v $ lock zeigt Ihnen die von einer Transaktion gehaltenen Sperren
Chris Saxon
@ ChrisSaxon: Du hast recht. Ich bezog mich auf die Tatsache, dass Sie nicht sehen können, welche Zeilen gesperrt wurden - ich hätte klarer sein sollen.
a_horse_with_no_name
Oracle (im Gegensatz zu anderen Datenbanken) hat keine gemeinsame Struktur für Sperren. Dies macht die Datenbank skalierbar, aber andererseits können Sie nicht alle Sperren sehen. Sperren werden direkt in Datenbankblöcken gespeichert. In dem Moment, in dem jemand blockiert wird, wird eine Struktur "Halter-Kellner" erstellt. Dann sehen Sie dieses Paar in V$LOCK.
ibre5041

Antworten:

13

Sie können nicht wirklich alle Zeilen auflisten, die von einer Sitzung gesperrt werden. Sobald jedoch eine Sitzung von einer anderen blockiert wird, können Sie feststellen, welche Sitzung / Zeile sie blockiert.

Oracle führt keine Liste einzelner Zeilensperren. Sperren werden vielmehr direkt in den Zeilen selbst registriert - stellen Sie sich das als zusätzliche Spalte vor.

Sie können über die V$LOCKAnsicht herausfinden, welche Sitzung eine Sperre für ein Objekt erhalten hat. Dabei werden jedoch nur allgemeine Informationen aufgelistet, nicht auf Zeilenebene.

In dieser Ansicht können Sie auch feststellen, ob eine Sitzung von einer anderen blockiert wird. In diesem Fall werden die Zeileninformationen in den Informationen angezeigt , wenn eine Sitzung von einer anderen Sitzung blockiert wird V$SESSION.

Sie können die Zeilen-ID abrufen. Erstellen Sie ein Beispiel mit zwei Sitzungen:

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 */

Sitzung 2 wartet jetzt auf Sitzung 1. Wir können die blockierende Zeile mit folgender Adresse ermitteln :

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

Zur weiteren Lektüre: eine Beschreibung des Prozesses von Tom Kyte .

Vincent Malgrat
quelle
3

Sie können alle Tabellensperren in einer Oracle-Datenbank finden, indem Sie die folgende Abfrage ausführen

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
quelle