Использование таблицы блокировки Oracle DB - PullRequest
2 голосов
/ 02 февраля 2011

Недавно у меня была задача, согласно которой мне нужно было иметь определенную функциональность блокировки. Конкретное было связано с:

  1. Транзакция, которая обновлялась стол был распределен, поэтому у меня не было контролировать его,
  2. В течение дня тысячи неблокирующих транзакций должны быть поддержаны одновременно, давайте назовем их «общими» операциями,
  3. Каждая «общая» операция обновляла строки в определенной «ветви» («LDN», «NY», «LA» ...),
  4. Один раз в день есть «мастер» операции для каждой ветви, которые происходят по разному, на разных ветках,
    1. Во время основной операции нет могут произойти «общие» операции в этой ветви.
    2. Когда операция «master» запускается должен ждать текущего «генерала» операция по предоставленному завершению филиала, которые были в системе до того, как прибыла операция «master».
    3. Во время обработки 'master' в определенной ветви, все остальные ветви могут быть обновлен.

Для архивации я создал таблицу Oracle DB

create table BRANCH_LOCK(
    BRANCH VARCHAR2(10),
    FLAG   VARCHAR2(1),
    CONSTRAINT "PK_BRANCH_LOCK" PRIMARY KEY ("BRANCH")
)

Поддерживались следующие функции для различных операций:

Для «общих» операций:

1. In the same XA transaction each operation locks BRANCH_LOCK table 
   in SHARE mode,
2. After locking it checks FLAG, on updated branch,
  1. If flag is 'Y', that means that currently 'master' 
      operation is in progess, so  Exception is thrown, 
     and no further processing is done;
  2. If flag is 'N' than everything is OK, and general processing is done;

Для основной операции:

  1. Когда приходит операция 'master', я запускаю отдельную транзакцию, которая:
    1. Блокировка таблицы BRANCH_LOCK в режиме EXCLUSIVE, которую транзакция не может получить, пока в этой таблице есть блокировка режима SHARE в другой транзакции (таким образом, я гарантирую, что операция «master» начнется после завершения всех текущих «общих» операций, хотя ждет транзакций по всем веткам закончить, не только указанную)
    2. Устанавливает флаг для ветви на 'Y' (Таким образом, я гарантирую, что не будет «общих» транзакций, пока «мастер» операция обработки),
  2. Во входящей транзакции я изменяю флаг в таблице на 'N', поэтому после он фиксирует BRANCH_LOG таблица будет иметь соответствующее значение в столбце FLAG, и система будет уметь обрабатывать «общее» операции снова.

Это еще не было в производстве, так что мне интересно, есть ли лучшее решение для этого, и есть ли еще недостатки, кроме описанного?

Некоторые обновления, о которых я не упоминал:

  1. Операция «Master» работает с результатами «общих» операций, поэтому крайне важно, чтобы ни одна «общая» операция не терялась во время обработки «master», поэтому текущая «общая» операция должна завершиться, прежде чем master операция начала обработки.
  2. Несколько «общих» операций в одной и той же ветке происходят каждую секунду, около 3000 операций в секунду,
  3. Для ветви может выполняться только одна «главная» операция, одновременно могут обрабатываться несколько «основных» операций в разных филиалах.

Ответы [ 3 ]

2 голосов
/ 02 февраля 2011

Вместо того, чтобы создавать свою собственную таблицу блокировок, я думаю, что я попытался бы использовать пакет блокировки Oracle DBMS_LOCK.

Это более эффективно, чем использование DML для выполнения блокировок, и это то, что Oracle использует внутренне для выполнения блокировки очереди.

2 голосов
/ 02 февраля 2011

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

0 голосов
/ 03 февраля 2011

Что такое объем таблицыблокировка этих веток завершена, затем do_master снимает блокировки, останавливая любые другие общие обновления до тех пор, пока не выполнит фиксацию.Затем эти общие обновления возобновляются.

Но если объемы большие, то этот SELECT ... FOR UPDATE может быть очень большим.Именно тогда я бы рассмотрел решение DBMS_LOCK.

...