Чтение - проверка - запись флага в базу данных - PullRequest
0 голосов
/ 08 июня 2018

В программе мы можем контролировать доступ к БД с несколькими процессами, используя синхронизированный блок.Какой подход мы можем использовать для сценария ниже.

  • Считать значение столбца из базы данных - скажем, flag
  • Если flag равно zero, обновите столбец флага как One
  • Выполните набор обработки в приложении, который должен быть защищен с помощью flag (Другой экземпляр приложения не должен выполнять эту операцию, пока flag не будет установлен в ноль)
  • Обновите столбец flag еще раз до zero

Существует несколько экземпляров приложений, выполняющих вышеуказанную операцию, указывающих на одну и ту же таблицу БД.Как мы можем синхронизировать этот процесс между экземплярами приложения?

Исследования выполнены

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

1 Ответ

0 голосов
/ 08 июня 2018

По моему опыту, вы не можете безопасно использовать значения в столбцах как способ "заблокировать" вещи.Если вам нужно сгенерировать блокировку, я предлагаю вам использовать подпрограммы в пакете DBMS_LOCK, например:

DECLARE
  strLock_handle  VARCHAR2(128);
  iResult         INTEGER;
  excpAllocate    EXCEPTION;

  PRAGMA EXCEPTION_INIT(excpAllocate, -20000);
BEGIN
  DBMS_LOCK.ALLOCATE_UNIQUE(lockname   => 'YOUR LOCK NAME',
                            lockhandle => strLock_handle);

  iResult := DBMS_LOCK.REQUEST(lockhandle        => strLock_handle,
                               lockmode          => DBMS_LOCK.X_MODE,  -- exclusive mode
                               timeout           => DBMS_LOCK.MAXWAIT,
                               release_on_commit => FALSE);

  IF iResult = 0 THEN
    -- Do what you need to do exclusively here - nothing else will be able to enter this
    -- section as they'll stall on the DBMS_LOCK.REQUEST call above.

    DBMS_OUTPUT.PUT_LINE('This is a stupid piece of example code');

    -- Note: if we changed the RELEASE_ON_COMMIT parameter passed to DBMS_LOCK.REQUEST
    -- above to TRUE, the following COMMIT would release all locks held
    -- by this process for which RELEASE_ON_COMMIT was TRUE.

    COMMIT;

    -- Release the lock acquired above. This will allow one of the (possibly
    -- many) processes stalled on the DBMS_LOCK.REQUEST above to proceed.

    iResult := DBMS_LOCK.RELEASE(strLock_handle);
  ELSE
    -- Lock was not acquired. Reasons are:
    --   iResult   Reason
    --   1         Timeout
    --   2         Deadlock
    --   3         Parameter error
    --   4         Already own lock specified
    --   5         Illegal lock handle

    DBMS_OUTPUT.PUT_LINE('DBMS_LOCK.REQUEST failed - iResult = ' || iResult);
  END IF;
EXCEPTION
  WHEN excpAllocate THEN
    DBMS_OUTPUT.PUT_LINE('DBMS_LOCK.ALLOCATE failed : ' || SQLCODE || ' ' || SQLERRM);
END;

Удачи.

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