Проблема
Предположим у нас есть PLSQL-функция записи в файл на диске. И есть функция удаления файла (например, чтобы начать записывать в новый). Значит во время удаления, ни одна другая сессия не должна писать в файл.
"Старое" решение
Можно сделать LOCK-таблицу с одним полем-PK, и при входе в функцию делать туда insert c константным ключём. Если вставка удачна, то выполняем код в самой функции и в конце строку из LOCK-таблицы. Любая другая сессия в это время при попытке вставки получит exception, который будет означать, что функция "заблокирована"
"Новое" решение
С некоторых пор (точно не знаю когда, но в 10-ке уже было), в БД Oracle появился пакет DBMS_LOCK, который предоставляет возможность блокировок в обычном программном ключе. Там есть возможности ожидания, shared и exclusive блокировок, ну и всё что в такого рода механизме должно быть.
Для нашего примера всё достаточно просто:
function turnFile return integer is
lockId varchar2(30);
lockCode number;
begin
--выделена блокировка
DBMS_LOCK.allocate_unique('MY_LOCK_NAME', lockId);
-- запрошена блокировка в исключительном режиме (0)
lockCode := DBMS_LOCK.request(lockId, dbms_lock.x_mode, 0);
-- если захватить не удалось, то выходим, очищая попытку блокировки
if lockCode <> 0 then
lockCode := DBMS_LOCK.release(lockId);
return;
end if;
-- что-то сделаем с файлом
...
-- снять блокировку
lockCode := DBMS_LOCK.release(lockId);
exception
when others then
-- снять блокировку, если что-то пошло не так
lockCode := DBMS_LOCK.release(lockId);
end turnFile;
Предположим у нас есть PLSQL-функция записи в файл на диске. И есть функция удаления файла (например, чтобы начать записывать в новый). Значит во время удаления, ни одна другая сессия не должна писать в файл.
"Старое" решение
Можно сделать LOCK-таблицу с одним полем-PK, и при входе в функцию делать туда insert c константным ключём. Если вставка удачна, то выполняем код в самой функции и в конце строку из LOCK-таблицы. Любая другая сессия в это время при попытке вставки получит exception, который будет означать, что функция "заблокирована"
"Новое" решение
С некоторых пор (точно не знаю когда, но в 10-ке уже было), в БД Oracle появился пакет DBMS_LOCK, который предоставляет возможность блокировок в обычном программном ключе. Там есть возможности ожидания, shared и exclusive блокировок, ну и всё что в такого рода механизме должно быть.
Для нашего примера всё достаточно просто:
function turnFile return integer is
lockId varchar2(30);
lockCode number;
begin
--выделена блокировка
DBMS_LOCK.allocate_unique('MY_LOCK_NAME', lockId);
-- запрошена блокировка в исключительном режиме (0)
lockCode := DBMS_LOCK.request(lockId, dbms_lock.x_mode, 0);
-- если захватить не удалось, то выходим, очищая попытку блокировки
if lockCode <> 0 then
lockCode := DBMS_LOCK.release(lockId);
return;
end if;
-- что-то сделаем с файлом
...
-- снять блокировку
lockCode := DBMS_LOCK.release(lockId);
exception
when others then
-- снять блокировку, если что-то пошло не так
lockCode := DBMS_LOCK.release(lockId);
end turnFile;