oracle locks - ghdrako/doc_snipets GitHub Wiki
Blokady na poziomie aplikacji, tj. blokady wierszy i tabel, mają tę negatywną cechę, że znacznie utrudniają wykonywanie. Domyślnie sesja oczekująca jest blokowana do momentu zwolnienia blokady przez sesję oczekującą. Aby to zrobić, konieczne jest zidentyfikowanie sesji blokujących i oczekujących.
Identyfikuje sesje blokując i sesje oczekujace
SELECT h.sid locking_sid,s.status status,s.program program_holding,
w.sid waiter_sid,sw.program program_waiting
FROM v$lock h,v$lock w,v$session s,v$session sw
WHERE (h.id1, h.id2) IN
(SELECT id1, id2 FROM v$lock WHERE request = 0
INTERSECT
SELECT id1, id2 FROM v$lock WHERE lmode = 0)
AND h.id1 = w.id1 AND h.id2 = w.id2 AND h.request = 0
AND w.lmode = 0 AND h.sid = s.sid AND w.sid = sw.sid;
Wyświetl obiekty z blokadami
SELECT c.owner, c.object_name, c.object_type, b.sid,
2 b.serial#, b.status, b.osuser, b.machine
3 FROM v$locked_object a, v$session b, dba_objects c
4 WHERE b.sid = a.session_id AND a.object_id = c.object_id;
W przypadku baz danych z wieloma sesjami istotne jest poznanie zależności między sesjami blokującymi i blokowanymi, aby móc opracować strategię rozwiązania sytuacji. Polecenie SQL w listingu 1.41 wyświetla zależności w formie struktury drzewa.
SELECT LPAD(' ', LEVEL )||sid sid, blocking_session, object_name,
2 q.sql_text
3 FROM v$session s, dba_objects o, v$sql q
4 WHERE (sid IN (SELECT blocking_session FROM v$session)
5 OR blocking_session IS NOT NULL)
6 AND o.object_id (+) = s.row_wait_obj#
7 AND q.sql_id (+) = s.sql_id
8 CONNECT BY PRIOR sid = blocking_session
9 START WITH blocking_session IS NULL;
SID BLOCKING OBJECT_N SQL_TEXT
-------- -------- -------- ---------------------------------------------
37
237 37 ORDERS update doag.orders set cnt=1
where order_id=1151
271 237 ORDERS update doag.orders set cnt=1
where order_id=1150
284 37 ORDERS update doag.orders set cnt=5
where order_id=1151