Отображение строк, заблокированных в Oracle - PullRequest
2 голосов
/ 02 марта 2011

Используя Oracle, можно ли указать, какие строки заблокированы (а какие нет) при выполнении оператора select (я не хочу блокировать какие-либо строки, просто могу отображать заблокированные)?

Например, псевдостолбец, который возвращает блокировку / транзакцию для строки:
ВЫБЕРИТЕ имя замка ОТ emp;

Ответы [ 3 ]

5 голосов
/ 02 марта 2011

Одна вещь, которую вы могли бы сделать, это - хотя это не очень эффективно, и поэтому я не хотел бы использовать это для больших наборов данных.Создайте функцию уровня строки, чтобы попытаться заблокировать строку.Если это не удастся, то строка уже заблокирована

    CREATE OR REPLACE FUNCTION is_row_locked (v_rowid ROWID, table_name VARCHAR2)
   RETURN varchar2
IS
   x   NUMBER;
   PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
   EXECUTE IMMEDIATE    'Begin
                           Select 1 into :x from '
                              || table_name
                              || ' where rowid =:v_rowid for update nowait;
                         Exception
                            When Others Then
                              :x:=null;
                         End;'
   USING OUT x, v_rowid;

   -- now release the lock if we got it. 
   ROLLBACK;

   IF x = 1
   THEN
      RETURN 'N';
   ELSIF x IS NULL
   THEN
      RETURN 'Y';
   END IF;
END;
/

И тогда вы сможете

Select field1, field2, is_row_locked(rowid, 'MYTABLE') from mytable;

Это будет работать, но это не красиво и не эффективно.

Действительно, у него есть только одно искупительное качество - оно будет работать, даже если у вас нет выделенных привилегий в различных таблицах v $, требуемых в связанном документе.Но если у вас есть привилегии, определенно идите другим путем.

2 голосов
/ 03 марта 2011

Я думаю, что ответ @Michael Broughton - единственный способ, который всегда будет работать.Это связано с тем, что V $ LOCK не точен в 100% случаев.

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

Например:

  • Сессия 1 создает точку сохранения и изменяет строку.
  • Сессия 2 пытается изменить эту же строку, но видит, что сессия 1 уже имеет эту строку, и ожидает завершения сессии 1.
  • Сессия 1 откатывается до точки сохранения.Это удаляет его запись из ITL, но не завершает транзакцию.Сессия 2 все еще ожидает сеанса 1. Согласно V $ LOCK, сессия 2 все еще ожидает этой строки, но это не совсем так, потому что теперь сеанс 3 может изменять эту строку.(И если сеанс 1 выполняет фиксацию или откат, сеанс 2 будет ожидать сеанса 3.)

Извините, если это сбивает с толку.Вы можете перейти по ссылке, предоставленной OMG Ponies, а затем повторить попытку с точками сохранения.

2 голосов
/ 02 марта 2011

можно указать, какие строки заблокированы (а какие нет) при выполнении оператора выбора

Оператор SELECT никогда не блокирует строки- если вы не попросите об этом с помощью FOR UPDATE.

Если вы хотите увидеть блокировки, удерживаемые из-за SELECT ... FOR UPDATE (или реального обновления), вы можете запросить систему v $ lockПосмотреть.

См. Ссылку, которую OMG Pony разместил для примера использования этого представления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...