sql >> Databáze >  >> RDS >> Oracle

Jak udělat MERGE serializovatelným

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.



  1. SQL dotaz nepoužívá dostupný index (SQL Server 2008)

  2. Co je literál Null Character v TSQL?

  3. ISO-8859-1 Znak zkrátí text vkládaný do utf-8 mysql sloupce

  4. Zadání názvu proměnné v klauzuli QUERY WHERE v JDBC