Det er faktisk præcis sådan indlejrede transaktioner blev designet til. Jeg citerer fra oracle docs:
Altså en underordnet transaktion i en almindelig indlejret transaktion har ingen indflydelse på, hvordan han eller de andre børn eller forælder (større transaktion). ) kunne opføre sig, andet end at ændre gensidige data eller fejle for en undtagelse.
Men du kan give ham (underordnet transaktion ) en meget begrænset mulighed for at stemme på sin skæbne ved at bruge sub-transaction
funktion som angivet på rails dokumenter
ved at sende 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
Hvilket som lægerne siger:skaber kun 'Kotori'. siden det magtfulde 'Nemu'-barn valgte at dø stille.
Flere oplysninger om indlejrede transaktionsregler (oracle-dokumenter )
Opdatering:
For bedre at forstå, hvorfor skinner nested transactions
fungerer på denne måde, skal du vide lidt mere om, hvordan indlejrede transaktioner fungerer på DB-niveau, jeg citerer fra rails api-dokumenter
:
Ok, så beskriver dokumenterne adfærden for en nested transaction
i de to nævnte tilfælde som følger:
I tilfælde af et indlejret opkald, #transaction vil opføre sig som følger:
-
Blokken vil blive kørt uden at gøre noget. Alle databaseudsagn, der sker inden for blokken, tilføjes effektivt til den allerede åbne databasetransaktion.
-
Men hvis :requires_new er indstillet, vil blokken blive pakket ind i et databaselagringspunkt, der fungerer som en undertransaktion.
Jeg forestiller mig forsigtig, kun forestil mig at:
mulighed(1) (uden requires_new) er der, hvis du brugte et DBMS, der fuldt ud understøtter nested transactions
eller du er tilfreds med den "falske" adfærd af nested_attributes
mens mulighed(2) er at understøtte savepoint
løsning, hvis du ikke gør det.