Когда запись заблокирована в Oracle, можем ли мы знать, какая запись заблокирована?

10

Когда запись заблокирована, мы можем знать, какая из них заблокирована?

Как я могу получить запись rowid или другую информацию?


Я могу получить некоторую информацию по этому 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(+) 

Я нашел метод в Интернете, чтобы получить rowid с помощью функции DBMS_ROWID.ROWID_CREATE()

Но это не похоже на работу.

iafanda
источник
2
Вы можете видеть только блокировки, которые ожидает какой-то процесс, но не те, которые удерживаются транзакцией.
a_horse_with_no_name
@a_horse_with_no_name - v $ lock показывает блокировки, удерживаемые транзакцией
Крис Саксон,
@ChrisSaxon: Вы правы. Я имел в виду тот факт, что вы не можете видеть, какие строки были заблокированы - я должен был быть более ясным.
a_horse_with_no_name
Oracle (в отличие от других баз данных) не имеет общей структуры для блокировок. Это делает базу данных масштабируемой, но, с другой стороны, вы не можете видеть все блокировки. Блокировки хранятся в блоках базы данных напрямую. В тот момент, когда кто-то блокируется, создается структура "держатель-официант". Тогда вы увидите эту пару в V$LOCK.
ibre5041

Ответы:

13

Вы не можете в действительности перечислить все строки, которые заблокированы сеансом. Однако, как только сеанс блокируется другим, вы можете найти, какой сеанс / строка его блокирует.

Oracle не поддерживает список отдельных блокировок строк. Скорее, блокировки регистрируются непосредственно внутри самих строк - воспринимайте это как дополнительный столбец.

Вы можете найти, какой сеанс получил блокировку объекта через V$LOCKпредставление, но в нем будет показана только общая информация, а не на уровне строк.

С помощью этого представления вы также можете определить, был ли сеанс заблокирован другим. В этом случае, если сеанс заблокирован другим сеансом, информация о строке отображается в V$SESSIONинформации.

Вы можете получить rowid, давайте создадим пример с двумя сессиями:

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

Сессия 2 теперь ожидает на Сессии 1. Мы можем обнаружить блокирующую строку с помощью:

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

Для дальнейшего чтения: описание процесса Тома Кайта .

Винсент Малграт
источник
3

Вы можете найти все блокировки таблиц в базе данных Oracle, выполнив следующий запрос

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;
Баджи Шайк
источник