Transaksi dalam SQL adalah unit eksekusi yang mengelompokkan satu atau lebih tugas bersama-sama. Suatu transaksi dianggap berhasil jika semua tugas di dalamnya dijalankan tanpa kesalahan.
Namun, jika salah satu tugas dalam transaksi gagal dijalankan, seluruh transaksi akan gagal. Sebuah transaksi hanya memiliki dua hasil:berhasil atau gagal.
Skenario Praktis
Pertimbangkan contoh praktis dari ATM (Anjungan Tunai Mandiri). Anda pergi ke ATM dan meminta kartu Anda. Ini menjalankan kueri untuk memeriksa apakah kartu itu valid atau tidak. Selanjutnya, ia meminta Anda untuk kode pin Anda. Sekali lagi itu menjalankan kueri untuk mencocokkan kode pin. ATM kemudian menanyakan jumlah yang ingin Anda tarik dan Anda memasukkan jumlah yang Anda inginkan. ATM mengeksekusi permintaan lain untuk mengurangi jumlah itu dari akun Anda dan kemudian membagikan dana kepada Anda.
Bagaimana jika jumlah tersebut dipotong dari akun Anda dan kemudian sistem mogok karena listrik padam tanpa mengeluarkan catatan?
Ini bermasalah karena dana pelanggan dipotong tanpa menerima uang. Di sinilah transaksi bisa berguna.
Jika terjadi kerusakan sistem atau kesalahan lainnya, semua tugas dalam transaksi dibatalkan. Oleh karena itu, dalam kasus ATM, jumlah tersebut akan ditambahkan kembali ke rekening Anda jika Anda tidak dapat menariknya karena alasan apa pun.
Apa itu Transaksi?
Paling sederhana, perubahan dalam tabel database adalah transaksi. Oleh karena itu, pernyataan INSERT, UPDATE dan DELETE adalah semua pernyataan transaksi. Saat Anda menulis kueri, transaksi dilakukan. Namun, transaksi ini tidak dapat dibatalkan. Kita akan melihat bagaimana transaksi dibuat, dikomit, dan dibatalkan di bawah, tetapi pertama-tama mari kita buat beberapa data dummy untuk digunakan.
Menyiapkan Data
Jalankan skrip berikut di server database Anda.
CREATE DATABASE schooldb CREATE TABLE student ( id INT PRIMARY KEY, name VARCHAR(50) NOT NULL, gender VARCHAR(50) NOT NULL, age INT NOT NULL, total_score INT NOT NULL, ) INSERT INTO student VALUES (1, 'Jolly', 'Female', 20, 500), (2, 'Jon', 'Male', 22, 545), (3, 'Sara', 'Female', 25, 600), (4, 'Laura', 'Female', 18, 400), (5, 'Alan', 'Male', 20, 500)
Skrip SQL di atas membuat database schooldb. Dalam database ini, tabel siswa dibuat dan beberapa data dummy ditambahkan ke tabel itu.
Melaksanakan Kueri tanpa Transaksi
Mari kita jalankan tiga kueri standar. Kami tidak menggunakan transaksi saat ini.
INSERT INTO student VALUES (6, 'Suzi', 'Female', 25, 395) UPDATE student SET age = 'Six' WHERE id= 6 DELETE from student WHERE id = 6
Di sini kueri pertama memasukkan catatan siswa ke dalam database. Kueri kedua memperbarui usia siswa dan kueri ketiga menghapus rekaman yang baru dimasukkan.
Jika Anda menjalankan skrip di atas, Anda akan melihat bahwa catatan akan dimasukkan ke dalam database dan kemudian akan terjadi kesalahan saat menjalankan kueri kedua.
Jika Anda melihat kueri kedua, kami memperbarui usia dengan menyimpan nilai string di kolom usia yang dapat menyimpan data tipe integer. Oleh karena itu kesalahan akan dilemparkan. Namun, kueri pertama masih akan berhasil diselesaikan. Ini berarti bahwa jika Anda memilih semua record dari tabel siswa, Anda akan melihat record yang baru dimasukkan.
[id tabel=23 /]
Anda dapat melihat bahwa record dengan id=6 dan nama 'Suzi' telah dimasukkan ke dalam database. Tetapi usia tidak dapat diperbarui dan kueri kedua gagal.
Bagaimana jika kita tidak menginginkan ini? Bagaimana jika kita ingin memastikan bahwa semua kueri berhasil dieksekusi atau tidak ada kueri yang dieksekusi sama sekali? Di sinilah transaksi menjadi berguna.
Melaksanakan Kueri dengan Transaksi
Sekarang mari kita jalankan ketiga query di atas dalam sebuah transaksi.
Pertama, mari kita lihat cara membuat dan melakukan transaksi.
Membuat Transaksi
Untuk menjalankan kueri/kueri sebagai transaksi, cukup bungkus kueri dalam kata kunci BEGIN TRANSACTION dan COMMIT TRANSACTION. BEGIN TRANSACTION menyatakan dimulainya TRANSAKSI sedangkan COMMIT TRANSACTION menyatakan bahwa transaksi telah selesai.
Mari kita jalankan tiga kueri baru pada database yang kita buat sebelumnya sebagai transaksi. Kami akan menambahkan rekor baru untuk siswa baru dengan ID 7.
BEGIN TRANSACTION INSERT INTO student VALUES (7, 'Jena', 'Female', 22, 456) UPDATE student SET age = 'Twenty Three' WHERE id= 7 DELETE from student WHERE id = 7 COMMIT TRANSACTION
Ketika transaksi di atas dijalankan, akan terjadi lagi kesalahan pada kueri kedua karena lagi-lagi nilai tipe string disimpan di kolom usia yang hanya menyimpan data tipe integer.
Namun, karena kesalahan terjadi di dalam transaksi, semua kueri yang berhasil dieksekusi sebelum kesalahan ini terjadi akan dibatalkan secara otomatis. Oleh karena itu, kueri pertama yang memasukkan catatan siswa baru dengan id =7 dan nama 'Jena' juga akan dibatalkan.
Sekarang, jika Anda memilih semua catatan dari tabel siswa, Anda akan melihat bahwa catatan baru untuk 'Jena' belum dimasukkan.
Pengembalian Transaksi Manual
Kami tahu jika kueri memunculkan kesalahan dalam suatu transaksi, seluruh transaksi, termasuk semua kueri yang sudah dieksekusi, secara otomatis dibatalkan. Namun, kami juga dapat mengembalikan transaksi secara manual kapan pun kami mau.
Untuk mengembalikan transaksi, kata kunci ROLLBACK digunakan diikuti dengan nama transaksi. Untuk menamai transaksi, sintaks berikut digunakan:
BEGIN TRANSACTION Transaction_name
Misalkan kita ingin tabel siswa kita tidak memiliki catatan yang berisi nama siswa duplikat. Kami akan menambahkan catatan untuk siswa baru. Kami kemudian akan memeriksa apakah siswa dengan nama yang sama dengan nama siswa yang baru dimasukkan ada di database. Jika siswa dengan nama itu belum ada, kami akan melakukan transaksi kami. Jika seorang siswa dengan nama itu memang ada, kami akan mengembalikan transaksi kami. Kami akan menggunakan pernyataan kondisional dalam kueri kami.
Perhatikan transaksi berikut:
DECLARE @NameCount int BEGIN TRANSACTION AddStudent INSERT INTO student VALUES (8, 'Jacob', 'Male', 21, 600) SELECT @NameCount = COUNT(*) FROM student WHERE name = 'Jacob' IF @NameCount > 1 BEGIN ROLLBACK TRANSACTION AddStudent PRINT 'A student with this name already exists' END ELSE BEGIN COMMIT TRANSACTION AddStudent PRINT 'New record added successfully' END
Perhatikan baik-baik skrip di atas. Banyak hal yang terjadi di sini.
Pada baris pertama, kita membuat variabel SQL tipe integer NameCount.
Selanjutnya, kita memulai transaksi bernama ‘AddStudent’. Anda dapat memberikan nama apapun untuk transaksi Anda.
Di dalam transaksi tersebut, kami memasukkan record baru untuk seorang siswa dengan id =8 dan nama 'Jacob'.
Selanjutnya, menggunakan fungsi agregat COUNT kami menghitung jumlah catatan siswa dengan nama 'Jacob' dan menyimpan hasilnya dalam variabel 'NameCount'.
Jika nilai variabel lebih besar dari 1, berarti siswa dengan nama 'Jacob' sudah ada di database. Dalam hal ini, kami ROLLBACK transaksi kami dan CETAK pesan di layar bahwa 'Seorang siswa dengan nama ini sudah ada'.
Jika tidak, kami melakukan transaksi kami dan menampilkan pesan 'Data baru berhasil ditambahkan'.
Saat Anda menjalankan transaksi di atas untuk pertama kalinya, tidak akan ada catatan siswa dengan nama 'Jacob'. Oleh karena itu transaksi akan dilakukan dan pesan berikut akan dicetak:
Sekarang coba jalankan skrip SQL berikut di server:
DECLARE @NameCount int BEGIN TRANSACTION AddStudent INSERT INTO student VALUES (9, 'Jacob', 'Male', 22, 400) SELECT @NameCount = COUNT(*) FROM student WHERE name = 'Jacob' IF @NameCount > 1 BEGIN ROLLBACK TRANSACTION AddStudent PRINT 'A student with this name already exists' END ELSE BEGIN COMMIT TRANSACTION PRINT 'New record added successfully' END
Di sini sekali lagi, kami memasukkan catatan siswa dengan id =9 dan nama 'Jacob'. Karena catatan siswa dengan nama 'Jacob' sudah ada di database, transaksi akan dibatalkan dan pesan berikut akan dicetak:
Tautan Berguna
- Kelas tentang transaksi SQL