Ve skutečnosti přesně takto vnořené transakce byl navržen pro. Cituji z oracle docs:
Tedy podřízená transakce v běžné vnořené transakci nemá žádné slovo ohledně toho, jak on nebo ostatní děti nebo rodič (větší transakce ) by se mohly chovat jinak než změnami vzájemných dat nebo selháním výjimky.
Ale můžete mu udělit (podřízenou transakci ) velmi omezená šance na hlasování o jeho osudu pomocí sub-transaction
funkce, jak je uvedeno u rails docs
předáním requires_new: true
User.transaction do
User.create(username: 'Kotori')
User.transaction(requires_new: true) do
User.create(username: 'Nemu')
raise ActiveRecord::Rollback
end
end
Což, jak říkají dokumenty:vytváří pouze 'Kotori'. protože mocné 'Nemu' dítě se rozhodlo zemřít tiše.
Další podrobnosti o pravidlech vnořených transakcí (dokumenty Oracle )
Aktualizace:
Abychom lépe pochopili, proč rails nested transactions
funguje tímto způsobem, potřebujete vědět trochu více o tom, jak fungují vnořené transakce na úrovni DB, cituji z rails api docs
:
Dobře, pak dokumenty popisují chování nested transactions
ve dvou zmíněných případech takto:
V případě vnořeného volání #transaction se bude chovat následovně:
-
Blok bude spuštěn, aniž by bylo cokoli provedeno. Všechny databázové příkazy, ke kterým dojde v rámci bloku, jsou účinně připojeny k již otevřené databázové transakci.
-
Pokud je však nastaveno :requires_new, blok bude zabalen do úložného bodu databáze, který bude fungovat jako dílčí transakce.
Představuji si opatrně, jen si představ že:
možnost (1) (bez require_new) je k dispozici v případě, že jste použili DBMS, který plně podporuje nested transactions
nebo jste spokojeni s "falešným" chováním nested_attributes
zatímco možnost (2) je podporovat savepoint
náhradní řešení, pokud tak neučiníte.