In realtà questo è esattamente come Transazioni nidificate è stato progettato per. Cito da Oracle Docs:
Quindi, una transazione secondaria in una normale transazione nidificata non ha voce in capitolo su come lui o gli altri figli o genitori (transazione più ampia ) potrebbe comportarsi diversamente dalla modifica dei dati reciproci o dal fallimento per un'eccezione.
Ma puoi concedergli (transazione figlio ) una possibilità di voto molto limitata sul suo destino utilizzando la sub-transaction
funzione come indicato in rails docs
passando 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
Che come dicono i documenti:crea solo 'Kotori'. dal momento che il potente bambino 'Nemu' ha scelto di morire in silenzio.
Maggiori dettagli sulle Regole delle transazioni nidificate (documenti Oracle )
Aggiornamento:
Per capire meglio perché blocca nested transactions
funziona in questo modo, devi sapere un po' di più su come funzionano le transazioni nidificate a livello di database, cito da documenti API Rails
:
Ok, allora i documenti descrivono il comportamento di una nested transaction
nei due casi citati come segue:
In caso di chiamata annidata, #transaction si comporterà come segue:
-
Il blocco verrà eseguito senza fare nulla. Tutte le istruzioni del database che si verificano all'interno del blocco vengono effettivamente aggiunte alla transazione del database già aperta.
-
Tuttavia, se :requires_new è impostato, il blocco verrà racchiuso in un punto di salvataggio del database che funge da sottotransazione.
Immagino attento, immagino solo che:
opzione(1) (senza require_new) è presente nel caso in cui tu abbia utilizzato un DBMS che supporta pienamente le nested transactions
oppure sei soddisfatto del comportamento "falso" di nested_attributes
mentre opzione(2) è supportare il savepoint
soluzione alternativa in caso contrario.