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

Mám spouštěč autonomní, ale spustím se pouze jednou ve stejné relaci

Používáte autonomní transakci k vyřešení skutečnosti, že spouštěč nemůže dotazovat svou tabulku sám. Narazili jste na nechvalně známou chybu mutující tabulky a zjistili jste, že deklarováním spouštěče jako autonomní transakce chyba zmizí.

Nemáte však štěstí, problém to vůbec neřeší:

  • Za prvé se ztratí veškerá transakční logika. Změny v suscription_fact nelze vrátit zpět tabulky, jsou zavázáni , zatímco vaše hlavní transakce není a mohla by být vrácena zpět. Takže jste také ztratili integritu dat.
  • Spouštěč nevidí nový řádek, protože nový řádek ještě nebyl potvrzen! Vzhledem k tomu, že spouštěč běží v nezávislé transakci, nemůže vidět nepotvrzené změny provedené hlavní transakcí:narazíte na zcela nesprávné výsledky.

To je důvod, proč byste nikdy neměli dělat žádnou obchodní logiku v autonomních transakcích. (Existují legitimní aplikace, ale jsou téměř zcela omezeny na protokolování/ladění).

Ve vašem případě byste měli buď:

  1. Aktualizujte svou logiku, aby se nemusela dotazovat na vaši tabulku (aktualizace suscription_fact pouze pokud je nový řádek novější než stará hodnota uložená v id_date_unsuscription ).
  2. Zapomeňte na používání obchodní logiky v triggerech a použijte proceduru, která aktualizuje všechny tabulky správně, nebo použijte zobrazení, protože zde máme jasný případ nadbytečných dat.
  3. Použijte řešení, které skutečně funguje (od Toma Kytea) .

Zde bych důrazně doporučil použít (2). Nepoužívejte spouštěče ke kódování obchodní logiky. Je těžké je napsat bez chyb a ještě těžší je udržovat. Použití procedury zaručuje, že veškerý relevantní kód je seskupen na jednom místě (balíček nebo procedura), snadno čitelný a následný a bez nepředvídaných následků.




  1. Jak předat proměnnou null do uložené procedury SQL z kódu C#.net

  2. TIME_FORMAT() Příklady – MySQL

  3. Jak převést mysql na sqlite3 pomocí PHP

  4. Laravel 5.4 Kombinace dvou kolekcí