Как заблокировать при выборе, а не просто вставить / обновить / удалить - PullRequest
2 голосов
/ 19 октября 2011

Допустим, у меня есть код, подобный следующему:

begin
  select ... from T where x = 42;         -- (1)
  .
  .
  .
  update T ... where x = 42;              -- (2)
  commit;
end;

Правильно ли я сказал, что к моменту выполнения (2) все, что было выбрано из T в (1), может уже не быть в T, если, например, в другом сеансе выполняется следующее:

delete from T where x = 42;

Если это так, то я бы хотел, чтобы оператор select блокировал T, поэтому его нельзя изменить.

Я понимаю, что могу сделать это явно, выполнив:

lock table T in exclusive mode;

Но что, если T - это представление? Должен ли я просматривать определение T s view / subviews, чтобы найти все таблицы, на которые он ссылается, и заблокировать их по отдельности, или я могу сделать что-то вроде этого:

begin
  START_TRANSACTION;
  select ... from T where x = 42;         -- (1)
  .
  .
  .
  update T ... where x = 42;              -- (2)
  commit;
end;

Где START_TRANSACTION обеспечивает блокировку всех таблиц, упомянутых во всех операторах выбора, до завершения транзакции?

Или есть еще более приятное решение этой проблемы? Я использую Oracle 10g, если это важно.

Ответы [ 3 ]

5 голосов
/ 19 октября 2011

Правильно ли я сказал, что к моменту выполнения (2) все, что было выбрано из T в (1), может уже не быть в T

Да.

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

SELECT ...
[INTO   ...]
FROM   T
WHERE  x = 42
FOR    UPDATE [NOWAIT];

При желании вы можете использовать NOWAIT, чтобы оператор не выполнялся, если кто-то уже заблокировал строку.Без NOWAIT оператор будет приостановлен, пока не сможет заблокировать строку.

2 голосов
/ 19 октября 2011

Вам необходимо использовать вариант select ... for update, как показано здесь .

Вы определенно не хотите заблокировать всю таблицу, хотя блокировка представления действительна. Из документов Oracle :

Когда в представлении выдается оператор LOCK TABLE, базовые базовые таблицы блокируются.

Тем не менее, это может быть причиной снижения производительности, и ваши администраторы баз данных найдут вас - скрывать некуда: -)

0 голосов
/ 19 октября 2011

Я почти уверен, что транзакция именно то, что вы хотите здесь. В справке указывается, что называется ACID для последовательности операций.

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