В программе мы можем контролировать несколько процессов, обращающихся к БД, с помощью синхронизированного блока. Какой подход мы можем использовать для сценария ниже.
flagflag - это zero, обновите столбец флагов как Oneflag не будет установлен в ноль)flag еще раз до zeroСуществует несколько экземпляров приложений, выполняющих указанную выше операцию, указывающую на одну и ту же таблицу БД. Как мы можем синхронизировать этот процесс между экземплярами приложения?
Исследование выполнено
Прочтите о блокировке таблиц БД и блокировках строк, но в моем случае чтение и запись - это две операции, которые должны работать как единица работы из другого экземпляра приложения.
Столбец флага универсален. Если какое-либо приложение установило флаг в 1, другое приложение не должно выполнять никаких операций.
Итак, что вы хотите, чтобы произошло, если какой-то другой процесс попытается установить флаг, пока кто-то другой его обрабатывает?
Может быть, посмотрите ВЫБРАТЬ ... ДЛЯ ОБНОВЛЕНИЯ ...




По моему опыту, вы не можете безопасно использовать значения в столбцах как способ «заблокировать» вещи. Если вам нужно сгенерировать блокировку, я предлагаю вам использовать подпрограммы из пакета 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;
Удачи.
Хороший пример Боб. К сожалению, я не верю, что это соответствует его требованию "чтение и запись - это две операции, которые должны работать как единица работы из разных экземпляров приложения.". Его требования несколько сбивают с толку: он не хочет, чтобы другие экземпляры приложения могли что-то делать, но он хочет, чтобы несколько экземпляров приложения могли что-то делать. Как узнать, какие экземпляры подходят для обновления, а какие нет. Если только несколько экземпляров не запущены в вашем разделе Делайте то, что вам нужно, исключительно здесь.
Существуют разные способы интерпретации вашего требования, и для них есть разные решения. Так что уточните, пожалуйста, свой вопрос. Действует ли «набор обработки» на таблицу с
flagили на другие таблицы / наборы данных? Есть ли только один экземплярflag, который применяется повсеместно во всем приложении, или есть несколько экземпляров флага, которые идентифицируют несколько "наборы обработки"?