Изключението, което виждате, е пряка последица от използването на стриктна сериализация. Ако имате повече от една активна транзакция едновременно, всяка от които е започнала с SET TRANSACTION ISOLATION LEVEL SERIALIZABLE, когато някоя от тях ангажира останалите, ще получи ORA-08177. Ето как се налага стриктна сериализация - базата данни хвърля ORA-08177 във всяка сесия, стартирана с ISOLATION LEVEL SERIALIZABLE, ако друга транзакция се ангажира в таблица, от която сериализиращата сесия се нуждае. Така че, основно, ако наистина се нуждаете от стриктна сериализация, трябва да боравите с ORA-08177 интелигентно, както е показано по-долу:
DECLARE
bSerializable_trans_complete BOOLEAN := FALSE;
excpSerializable EXCEPTION;
PRAGMA EXCEPTION_INIT(excpSerializable, -08177);
BEGIN
<<SERIALIZABLE_LOOP>>
WHILE NOT bSerializable_trans_complete
LOOP
BEGIN
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
MERGE ...; -- or whatever
COMMIT;
bSerializable_trans_complete := TRUE; -- allow SERIALIZABLE_LOOP to exit
EXCEPTION
WHEN excpSerializable THEN
ROLLBACK;
CONTINUE SERIALIZABLE_LOOP;
END;
END LOOP; -- SERIALIZABLE_LOOP
END;
Сериализацията не е магия и не е „безплатна“ (където „безплатна“ означава „аз като разработчик не трябва да правя нищо, за да работи правилно“). Изисква повече планиране и работа от страна на разработчика, за да функционира правилно, не по-малко. Споделяйте и се наслаждавайте.