Приведенный ниже код найдет все заблокированные строки в таблице.
(Однако вам, вероятно, не нужно запускать этот код. Если у вас возникла проблема с блокировкой, обычно легче найти виновного, используя GV$SESSION.BLOCKING_SESSION
и другие связанные представления словаря данных. Пожалуйста, попробуйте другой подход перед запуском это ужасно медленный код.)
Во-первых, давайте создадим пример таблицы и некоторые данные. Запустите это в сессии № 1.
--Sample schema.
create table test_locking(a number);
insert into test_locking values(1);
insert into test_locking values(2);
commit;
update test_locking set a = a+1 where a = 1;
В сеансе # 2 создайте таблицу для хранения заблокированных идентификаторов ROWID.
--Create table to hold locked ROWIDs.
create table locked_rowids(the_rowid rowid);
--Remove old rows if table is already created:
--delete from locked_rowids;
--commit;
В сеансе # 2 запустите этот блок PL / SQL, чтобы прочитать всю таблицу, проверить каждую строку и сохранить заблокированные ROWID. Имейте в виду, это может быть смехотворно медленным. В вашей реальной версии этого запроса измените обе ссылки на TEST_LOCKING на свою собственную таблицу.
--Save all locked ROWIDs from a table.
--WARNING: This PL/SQL block will be slow and will temporarily lock rows.
--You probably don't need this information - it's usually good enough to know
--what other sessions are locking a statement, which you can find in
--GV$SESSION.BLOCKING_SESSION.
declare
v_resource_busy exception;
pragma exception_init(v_resource_busy, -00054);
v_throwaway number;
type rowid_nt is table of rowid;
v_rowids rowid_nt := rowid_nt();
begin
--Loop through all the rows in the table.
for all_rows in
(
select rowid
from test_locking
) loop
--Try to look each row.
begin
select 1
into v_throwaway
from test_locking
where rowid = all_rows.rowid
for update nowait;
--If it doesn't lock, then record the ROWID.
exception when v_resource_busy then
v_rowids.extend;
v_rowids(v_rowids.count) := all_rows.rowid;
end;
rollback;
end loop;
--Display count:
dbms_output.put_line('Rows locked: '||v_rowids.count);
--Save all the ROWIDs.
--(Row-by-row because ROWID type is weird and doesn't work in types.)
for i in 1 .. v_rowids.count loop
insert into locked_rowids values(v_rowids(i));
end loop;
commit;
end;
/
Наконец, мы можем просмотреть заблокированные строки, присоединившись к таблице LOCKED_ROWIDS.
--Display locked rows.
select *
from test_locking
where rowid in (select the_rowid from locked_rowids);
A
-
1