Menu

Savepoint SQLite: Transaksi Bersarang, ROLLBACK TO

Cara kerja savepoint di SQLite: penanda bernama di dalam transaksi yang bisa kamu kembalikan tanpa membuang seluruh transaksinya.

Halaman ini dilengkapi editor yang bisa dijalankan. Edit, jalankan, dan lihat output-nya seketika.

Savepoint Adalah Penanda Bernama di Dalam Transaksi

Transaksi biasa bersifat semua atau tidak sama sekali: semua yang ada di antara BEGIN dan COMMIT diterapkan bersama-sama atau dibuang bersama-sama. Biasanya itulah yang kamu mau, tapi terkadang kamu ingin kontrol yang lebih halus. "Coba kelompok perubahan ini; kalau gagal, batalkan kelompok itu saja dan biarkan sisa transaksinya tetap berjalan."

Itulah savepoint. Kamu memasang penanda bernama, mengerjakan sesuatu, lalu memilih untuk mempertahankan pekerjaan itu (RELEASE) atau memutar balik ke penanda tersebut (ROLLBACK TO).

Pengurangan saldo Ada dan penambahan saldo Boris sama-sama tetap tersimpan. Update yang keliru ke Nobody dibatalkan tanpa kehilangan sisa transaksinya.

Tiga Perintahnya

Seluruh API-nya hanya tiga pernyataan:

  • SAVEPOINT name: memasang penanda.
  • RELEASE SAVEPOINT name: mempertahankan pekerjaan sejak penanda itu dipasang, lalu menghapus penandanya.
  • ROLLBACK TO SAVEPOINT name: membatalkan semua sejak penanda itu; penandanya tetap di tempat sehingga kamu bisa mencoba lagi.

Kata SAVEPOINT setelah RELEASE dan ROLLBACK TO itu opsional: RELEASE risky dan ROLLBACK TO risky sama-sama berfungsi.

Baris step 2 attempt tidak pernah ada sejauh menyangkut database akhirnya. Semua yang lain tersimpan.

Savepoint Tanpa Transaksi Luar

Ada sedikit kejutan: kamu bisa menjalankan SAVEPOINT tanpa BEGIN lebih dulu. SQLite diam-diam membuka transaksi untukmu, dan savepoint terluar berperan sebagai transaksinya. RELEASE pada savepoint itu melakukan commit, sedangkan ROLLBACK TO memutar balik tanpa commit.

Itulah sebabnya savepoint kadang disebut "transaksi bernama." Tapi mencampur kedua gaya ini di kode sungguhan jadi membingungkan, jadi pilih salah satu. Kebanyakan orang memakai BEGIN ... COMMIT yang eksplisit untuk batas luarnya, dan savepoint hanya untuk titik-titik pembatalan sebagian di dalamnya.

Savepoint Bersarang

Savepoint bisa ditumpuk. Kamu bisa memasang satu savepoint di dalam savepoint lain, lalu membatalkan yang di dalam tanpa menyentuh yang di luar:

Isi akhirnya: a, b, d. Kembali ke inner menghapus c, tapi pekerjaan yang dilakukan sebelum inner (insert b) tetap utuh, dan transaksinya terus berjalan.

Kembali ke savepoint luar juga membuang apa pun yang dilakukan di level dalam: seluruh tumpukan di atas nama itu terurai sekaligus:

b dan c sama-sama hilang. ROLLBACK TO outer memutar balik semua sejak outer dipasang, termasuk inner dan insert c.

Kenapa Memakai Savepoint?

Kasus klasiknya adalah memproses sekelompok data di mana item tertentu boleh gagal tanpa membatalkan seluruh kelompok. Bungkus setiap item dengan savepoint; jika gagal, kembali ke savepoint itu lalu lanjutkan:

Di kode aplikasi sungguhan, insert yang salah memunculkan error, lalu aplikasi menangkapnya, menjalankan ROLLBACK TO, dan melanjutkan. Dua baris yang benar tersimpan; baris yang salah tidak merusak seluruh kelompok.

Pola ini juga cara ORM dan tool migrasi mengimplementasikan transaksi bersarang. Mereka tidak benar-benar menyarangkan blok BEGIN (SQLite tidak mengizinkannya), melainkan memetakan panggilan bersarang ke savepoint.

Beberapa Hal yang Perlu Diwaspadai

Beberapa detail yang sering menjebak orang yang baru memakai savepoint:

  • COMMIT selalu melakukan commit seluruh transaksi. Tidak peduli berapa banyak savepoint yang masih terbuka, COMMIT (atau aliasnya END) menutup seluruh transaksi luar. Jangan anggap RELEASE sebagai commit sebagian; tidak ada yang tersimpan permanen sampai transaksi di sekitarnya di-commit.
  • ROLLBACK (tanpa TO) membatalkan semuanya. Perintah ini mengakhiri transaksi dan membuang semua savepoint yang terbuka. Pakai ROLLBACK TO name jika kamu ingin transaksinya tetap berjalan.
  • Savepoint tetap terbuka sampai di-release atau dilewati oleh rollback. Lupa melakukan RELEASE tidak membuat data hilang, tapi penandanya akan tetap ada sampai transaksinya berakhir.
  • Nama tidak wajib unik. Jika kamu memasang SAVEPOINT s dua kali, ROLLBACK TO s menemukan yang paling baru. Berguna untuk rekursi, tapi membingungkan jika tidak disengaja.

Selanjutnya: View

Savepoint memberimu kontrol yang lebih halus atas penulisan. Langkah berikutnya adalah membentuk cara kamu membaca: menyimpan sebuah query sebagai objek bernama yang bisa dipakai ulang dan bisa kamu SELECT seperti tabel. Itulah view, dan topik itu dibahas berikutnya.

Pertanyaan yang sering diajukan

Apa itu savepoint di SQLite?

Savepoint adalah penanda bernama yang kamu pasang di dalam sebuah transaksi. Nanti kamu bisa ROLLBACK TO ke nama itu untuk membatalkan semua yang dilakukan setelahnya, atau RELEASE untuk mempertahankan perubahannya dan membuang penandanya. Savepoint membuatmu bisa memperlakukan bagian-bagian transaksi sebagai unit yang lebih kecil dan bisa dipulihkan.

Apa perbedaan savepoint dan transaksi di SQLite?

Transaksi dimulai dengan BEGIN dan diakhiri dengan COMMIT atau ROLLBACK. Savepoint dipasang di dalam transaksi dengan SAVEPOINT name dan memberimu titik pembatalan sebagian. Kembali ke sebuah savepoint tidak mengakhiri transaksi di sekitarnya: kamu bisa terus bekerja dan melakukan commit nanti.

Bisakah savepoint SQLite bersarang?

Bisa. Kamu bisa menumpuk savepoint dengan nama yang berbeda, dan ROLLBACK TO outer membatalkan semuanya sampai ke level itu, termasuk savepoint di dalamnya. Nama tidak harus unik: SQLite memakai savepoint terbaru dengan nama itu, yang merupakan perilaku stack yang standar.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai