Transaksi adalah operasi atau kumpulan operasi yang dijamin bersifat atomik, yang berarti bahwa transaksi tidak pernah diterapkan sebagian. Semua operasi dalam transaksi tersebut akan diterapkan, atau tidak ada yang diterapkan. Transaksi memiliki durasi maksimum 60 detik dengan masa berlaku tidak ada aktivitas 10 detik setelah 30 detik.
Dengan API asinkron NDB, aplikasi dapat mengelola beberapa transaksi secara bersamaan jika transaksi tersebut independen.
API sinkron menawarkan API yang disederhanakan menggunakan
dekorator @ndb.transactional()
.
Fungsi yang didekorasi dijalankan dalam konteks transaksi.
Transaksi akan gagal jika transaksi tersebut "berbenturan" dengan transaksi lain; NDB akan otomatis mencoba kembali transaksi yang gagal tersebut beberapa kali.
Fungsi ini dapat dipanggil beberapa kali jika transaksi
dicoba lagi. Ada batas (default 3) jumlah percobaan ulang
; jika transaksi masih tidak berhasil, NDB akan memunculkan TransactionFailedError
. Anda dapat mengubah jumlah percobaan ulang
dengan meneruskan retries=N
ke
dekorator transactional()
.
Jumlah percobaan ulang 0 berarti transaksi dicoba sekali, tetapi tidak dicoba lagi jika gagal; jumlah percobaan ulang N berarti bahwa transaksi dapat dicoba hingga total N+1 kali. Contoh:
Dalam transaksi, hanya kueri ancestor yang diizinkan. Secara default, transaksi hanya dapat berfungsi dengan entity dalam entity group yang sama (entity yang kuncinya memiliki "ancestor" yang sama).
Anda dapat menentukan transaksi lintas grup ("XG") (yang memungkinkan hingga dua puluh lima grup entity), dengan meneruskan xg=True
:
Transaksi lintas grup beroperasi di beberapa entity group, dan berperilaku seperti transaksi satu grup, tetapi tidak akan gagal jika kode mencoba memperbarui entity dari lebih dari satu entity group.
Jika fungsi memunculkan pengecualian,
transaksi akan segera dibatalkan dan NDB memunculkan ulang
pengecualian sehingga kode panggilan melihatnya.
Anda dapat memaksa transaksi untuk gagal tanpa ada peringatan dengan memunculkan pengecualian ndb.Rollback
(dalam hal ini, panggilan fungsi menampilkan None
). Tidak ada mekanisme untuk memaksa percobaan ulang.
Anda mungkin memiliki fungsi yang tidak selalu ingin dijalankan dalam transaksi. Daripada mendekorasi fungsi tersebut
dengan @ndb.transactional
, teruskan sebagai fungsi
callback ke ndb.transaction()
Untuk menguji apakah beberapa kode berjalan di dalam transaksi, gunakan fungsi in_transaction()
.
Anda dapat menentukan perilaku fungsi "transaksional" jika dipanggil oleh kode yang sudah ada dalam transaksi. Dekorator
@ndb.non_transactional
menentukan bahwa fungsi
tidak boleh berjalan dalam transaksi; jika dipanggil dalam transaksi, fungsi akan berjalan di luar transaksi. Dekorator @ndb.transactional
dan fungsi ndb.transaction
menggunakan
argumen kata kunci propagation
. Misalnya, jika suatu fungsi
harus memulai transaksi independen baru, dekorasikan seperti ini:
Jenis propagasi tercantum bersama Opsi Konteks dan Opsi Transaksi lainnya
Perilaku transaksi dan perilaku caching NDB dapat digabungkan untuk membingungkan Anda jika Anda tidak tahu apa yang terjadi. Jika Anda mengubah entity di dalam transaksi tetapi belum meng-commit transaksi, cache konteks NDB memiliki nilai yang telah diubah, tetapi datastore yang mendasarinya masih memiliki nilai yang tidak diubah.
Antrean tugas transaksional
Anda dapat mengantrekan tugas sebagai bagian dari transaksi Datastore, sehingga tugas hanya diantrekan jika transaksi berhasil di-commit. Jika transaksi tidak di-commit, tugas tidak akan diantrekan. Jika transaksi di-commit, tugas akan diantrekan. Setelah diantrekan, tugas tidak akan langsung dieksekusi, sehingga tugas tersebut tidak atomik dengan transaksi. Namun, setelah diantrekan, tugas akan dicoba lagi hingga berhasil. Hal ini berlaku untuk setiap tugas yang diantrekan selama fungsi yang didekorasi.
Tugas transaksional berguna karena memungkinkan Anda menggabungkan tindakan non-Datastore ke transaksi yang bergantung pada keberhasilan transaksi (seperti mengirim email untuk mengonfirmasi pembelian). Anda juga dapat mengaitkan tindakan Datastore ke transaksi, misalnya untuk melakukan perubahan pada entity group di luar transaksi jika dan hanya jika transaksi berhasil.
Aplikasi tidak dapat menyisipkan lebih dari lima tugas transaksional ke dalam task queue selama satu transaksi. Tugas transaksional tidak boleh memiliki nama yang ditentukan pengguna.