Undantaget du ser är en direkt följd av strikt serialisering. Om du har mer än en transaktion aktiv samtidigt, började var och en med SET TRANSACTION ISOLATION LEVEL SERIALIZABLE, när någon av dem begår kommer de andra att få en ORA-08177. Det är så strikt serialisering upprätthålls - databasen kastar en ORA-08177 i valfri session som startas med ISOLATION LEVEL SERIALIZABLE om en annan transaktion commit in i en tabell som den serialiserbara sessionen behöver. Så, i princip, om du verkligen behöver strikt serialisering måste du hantera ORA-08177:s intelligent, som i följande:
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;
Serialisering är inte magi, och det är inte "gratis" (där "gratis" betyder "jag som utvecklare behöver inte göra något för att få det att fungera korrekt"). Det krävs mer planering och arbete från byggherren för att det ska fungera korrekt, inte mindre. Dela och njut.