Dit is eigenlijk precies hoe geneste transacties voor is ontworpen. Ik citeer uit orakeldocumenten:
Dus een onderliggende transactie in een gewone geneste transactie heeft geen zeggenschap over hoe hij of de andere kinderen of ouder (grotere transactie ) zich zou kunnen gedragen, behalve het wijzigen van wederzijdse gegevens of het niet slagen voor een uitzondering.
Maar je kunt hem (onderliggende transactie ) een zeer beperkte stemkans op zijn lot door gebruik te maken van de sub-transaction
functie zoals vermeld op rails docs
door requires_new: true
. door te geven
User.transaction do
User.create(username: 'Kotori')
User.transaction(requires_new: true) do
User.create(username: 'Nemu')
raise ActiveRecord::Rollback
end
end
Wat, zoals de documenten zeggen:alleen 'Kotori' creëert. sinds het machtige 'Nemu'-kind ervoor koos om in stilte te sterven.
Meer details over Geneste transactieregels (oracle docs )
Bijwerken:
Om beter te begrijpen waarom rails nested transactions
op deze manier werkt, moet je wat meer weten over hoe geneste transacties werken op DB-niveau, ik citeer uit rails api-documenten
:
Ok, dan beschrijven de documenten het gedrag van een nested transaction
in de twee genoemde gevallen als volgt:
In het geval van een geneste oproep, #transaction zal zich als volgt gedragen:
-
Het blok wordt uitgevoerd zonder iets te doen. Alle database-instructies die binnen het blok plaatsvinden, worden effectief toegevoegd aan de reeds geopende databasetransactie.
-
Als :requires_new echter is ingesteld, wordt het blok verpakt in een databaseopslagpunt dat als een subtransactie fungeert.
Ik stel me voorzichtig voor, stel je maar voor dat:
optie(1) (zonder vereist_new) is er voor het geval je een DBMS hebt gebruikt dat nested transactions
volledig ondersteunt of je bent tevreden met het "nep"-gedrag van nested_attributes
while optie(2) is om het savepoint
. te ondersteunen tijdelijke oplossing als u dat niet doet.