Wyjątek, który widzisz, jest bezpośrednią konsekwencją użycia ścisłej serializacji. Jeśli masz więcej niż jedną aktywną transakcję w tym samym czasie, każda z nich zaczynała się od opcji SET TRANSACTION ISOLATION LEVEL SERIALIZABLE, gdy którakolwiek z nich zatwierdzi, pozostałe otrzymają ORA-08177. W ten sposób wymuszana jest ścisła serializacja - baza danych wyrzuca ORA-08177 w dowolnej sesji rozpoczętej z ISOLATION LEVEL SERIALIZABLE, jeśli inna transakcja zostanie zatwierdzona do tabeli, której potrzebuje sesja serializowana. Tak więc, w zasadzie, jeśli naprawdę potrzebujesz ścisłej serializacji, musisz inteligentnie obsługiwać ORA-08177, jak poniżej:
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;
Serializacja nie jest magią i nie jest „darmowa” (gdzie „darmowa” oznacza „ja jako programista nie muszę nic robić, aby działała poprawnie”). To wymaga więcej planowania i pracy ze strony dewelopera, aby działała poprawnie, a nie mniej. Dziel się i ciesz.