Výjimka, kterou vidíte, je přímým důsledkem použití přísné serializace. Pokud máte současně aktivních více než jednu transakci, každá začíná s SET TRANSACTION ISOLATION LEVEL SERIALIZABLE, když kterýkoli z nich potvrdí, ostatní obdrží ORA-08177. Takto je vynucena přísná serializace – databáze vyvolá ORA-08177 v každé relaci zahájené s ÚROVEŇ IZOLACE SERIALIZABLE, pokud se do tabulky, kterou serializovatelná relace potřebuje, zapíše jiná transakce. Takže v zásadě, pokud opravdu potřebujete přísnou serializaci, musíte s ORA-08177 zacházet inteligentně, jako v následujícím:
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;
Serializace není kouzlo a není ani „zdarma“ (kde „zdarma“ znamená „já jako vývojář nemusím nic dělat, aby to fungovalo správně“). Správné fungování vyžaduje více plánování a práce ze strany vývojáře, nikoli méně. Sdílejte a užívejte si.