Sebenarnya beginilah cara Transaksi Bersarang dirancang untuk. Saya mengutip dari dokumen oracle:
Jadi, transaksi anak dalam transaksi bersarang biasa tidak memiliki suara tentang bagaimana dia atau anak-anak lain atau orang tua (transaksi lebih besar ) dapat berperilaku, selain mengubah data bersama atau gagal karena pengecualian.
Tapi Anda bisa memberinya (transaksi anak ) kesempatan voting yang sangat terbatas pada takdirnya dengan memanfaatkan sub-transaction
fitur seperti yang dinyatakan di rails dokumen
dengan mengirimkan 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
Seperti yang dikatakan dokumen:hanya membuat 'Kotori'. karena anak 'Nemu' yang kuat memilih untuk mati diam-diam.
Detail selengkapnya tentang Aturan transaksi bertingkat (dokumen oracle )
Pembaruan:
Untuk lebih memahami mengapa Rails nested transactions
bekerja dengan cara ini, Anda perlu tahu lebih banyak tentang cara kerja transaksi bersarang di tingkat DB, saya kutip dari dokumen rails api
:
Oke, kemudian dokumen menjelaskan perilaku nested transactions
dalam dua kasus yang disebutkan sebagai berikut:
Dalam kasus panggilan bersarang, #transaction akan berperilaku sebagai berikut:
-
Blok akan dijalankan tanpa melakukan apa pun. Semua pernyataan basis data yang terjadi di dalam blok secara efektif ditambahkan ke transaksi basis data yang sudah terbuka.
-
Namun, jika :requires_new disetel, blok akan dibungkus dalam savepoint database yang bertindak sebagai sub-transaksi.
Saya membayangkan hati-hati, bayangkan saja itu:
opsi(1) (tanpa membutuhkan_baru) apakah ada jika Anda menggunakan DBMS yang sepenuhnya mendukung nested transactions
atau Anda senang dengan perilaku "palsu" nested_attributes
sementara opsi(2) adalah untuk mendukung savepoint
solusi jika tidak.