Bayangkan sebuah skenario transfer uang antar rekening: uang sudah dikurangi dari rekening pengirim, namun tiba-tiba terjadi error sehingga penambahan ke rekening penerima tidak berhasil. Akibatnya, uang "hilang" dari sistem. Inilah masalah yang diselesaikan oleh Transaction di MySQL. Transaction memastikan sekelompok operasi SQL berhasil sepenuhnya atau gagal sepenuhnya โ tidak ada kondisi setengah jadi.
Konsep ACID
Transaction di database harus memenuhi empat properti ACID:
- Atomicity (Atomisitas): Semua operasi dalam satu transaction berhasil atau semua dibatalkan.
- Consistency (Konsistensi): Database selalu beralih dari satu state valid ke state valid lainnya.
- Isolation (Isolasi): Transaction yang berjalan bersamaan tidak saling menginterferensi.
- Durability (Ketahanan): Setelah COMMIT, perubahan tersimpan permanen meski terjadi crash.
Perintah Dasar Transaction
Ada tiga perintah utama dalam transaction MySQL:
START TRANSACTIONatauBEGIN: Memulai transaction baru.COMMIT: Menyimpan semua perubahan secara permanen.ROLLBACK: Membatalkan semua perubahan sejak transaction dimulai.
Persiapan Tabel Contoh
CREATE TABLE rekening (
id INT AUTO_INCREMENT PRIMARY KEY,
nama_pemilik VARCHAR(100) NOT NULL,
saldo DECIMAL(15, 2) NOT NULL DEFAULT 0.00,
CHECK (saldo >= 0)
) ENGINE=InnoDB;
INSERT INTO rekening (nama_pemilik, saldo) VALUES
('Andi Saputra', 5000000.00),
('Budi Santoso', 3000000.00);
Contoh Transaction Dasar: Transfer Saldo
-- Mulai transaction
START TRANSACTION;
-- Kurangi saldo pengirim
UPDATE rekening
SET saldo = saldo - 1000000
WHERE id = 1 AND saldo >= 1000000;
-- Periksa apakah update berhasil
-- Jika ROW_COUNT() = 0 berarti saldo tidak cukup
-- Maka kita ROLLBACK
-- Tambah saldo penerima
UPDATE rekening
SET saldo = saldo + 1000000
WHERE id = 2;
-- Jika semua berhasil, simpan permanen
COMMIT;
-- Cek saldo setelah transfer
SELECT * FROM rekening;
ROLLBACK โ Membatalkan Transaction
Jika ada error di tengah transaction, gunakan ROLLBACK untuk membatalkan semua perubahan:
START TRANSACTION;
UPDATE rekening SET saldo = saldo - 2000000 WHERE id = 1;
UPDATE rekening SET saldo = saldo + 2000000 WHERE id = 2;
-- Simulasi: ada error, batalkan semua
ROLLBACK;
-- Saldo kembali ke nilai semula
SELECT * FROM rekening;
SAVEPOINT โ Titik Simpan di Tengah Transaction
SAVEPOINT memungkinkan Anda membuat titik-titik checkpoint di dalam transaction, sehingga bisa ROLLBACK ke titik tertentu tanpa membatalkan seluruh transaction:
START TRANSACTION;
-- Operasi pertama
UPDATE rekening SET saldo = saldo - 500000 WHERE id = 1;
-- Buat savepoint setelah operasi pertama
SAVEPOINT setelah_debit;
-- Operasi kedua
UPDATE rekening SET saldo = saldo + 500000 WHERE id = 2;
-- Buat savepoint kedua
SAVEPOINT setelah_kredit;
-- Misalnya ada validasi yang gagal di sini
-- Rollback hanya ke savepoint tertentu
ROLLBACK TO SAVEPOINT setelah_debit;
-- Saldo rekening 2 kembali ke semula, tapi rekening 1 sudah dikurangi
-- Lanjutkan atau batalkan sepenuhnya
ROLLBACK; -- batalkan seluruhnya
-- Hapus savepoint yang tidak diperlukan
-- RELEASE SAVEPOINT setelah_debit;
Autocommit di MySQL
Secara default, MySQL berjalan dalam mode autocommit, artinya setiap pernyataan SQL langsung di-commit. Anda bisa menonaktifkannya:
-- Cek status autocommit
SELECT @@autocommit;
-- Nonaktifkan autocommit untuk sesi ini
SET autocommit = 0;
-- Sekarang setiap perubahan harus di-commit manual
UPDATE rekening SET saldo = saldo + 100000 WHERE id = 1;
COMMIT; -- wajib untuk menyimpan perubahan
-- Aktifkan kembali autocommit
SET autocommit = 1;
Menangani Transaction di Dalam Kode (Simulasi)
-- Simulasi transaction dengan penanganan error menggunakan prosedur
DELIMITER $$
CREATE PROCEDURE transfer_saldo(
IN p_dari INT,
IN p_ke INT,
IN p_jumlah DECIMAL(15,2),
OUT p_status VARCHAR(50)
)
BEGIN
DECLARE v_saldo_pengirim DECIMAL(15,2);
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
SET p_status = 'GAGAL: Terjadi error database';
END;
START TRANSACTION;
-- Ambil dan kunci saldo pengirim
SELECT saldo INTO v_saldo_pengirim
FROM rekening
WHERE id = p_dari
FOR UPDATE;
-- Validasi saldo cukup
IF v_saldo_pengirim < p_jumlah THEN
ROLLBACK;
SET p_status = 'GAGAL: Saldo tidak mencukupi';
ELSE
UPDATE rekening SET saldo = saldo - p_jumlah WHERE id = p_dari;
UPDATE rekening SET saldo = saldo + p_jumlah WHERE id = p_ke;
COMMIT;
SET p_status = 'BERHASIL';
END IF;
END$$
DELIMITER ;
-- Jalankan transfer
CALL transfer_saldo(1, 2, 750000, @hasil);
SELECT @hasil AS status_transfer;
SELECT * FROM rekening;
Tips Penting Transaction
- Jaga agar transaction sependek mungkin untuk menghindari lock yang terlalu lama.
- Gunakan
FOR UPDATEsaat membaca data yang akan dimodifikasi untuk mencegah race condition. - Transaction hanya bekerja pada storage engine yang mendukung ACID, seperti InnoDB. MyISAM tidak mendukung transaction.
- Selalu sertakan penanganan error (ROLLBACK) di dalam kode aplikasi Anda.
Kesimpulan
Transaction adalah fitur krusial di MySQL untuk menjamin integritas data dalam operasi yang melibatkan beberapa langkah. Dengan START TRANSACTION, COMMIT, dan ROLLBACK, Anda bisa memastikan bahwa sekelompok operasi SQL berhasil sepenuhnya atau tidak sama sekali. Gunakan SAVEPOINT untuk kontrol yang lebih granular di dalam transaction kompleks. Selalu pastikan storage engine yang Anda gunakan adalah InnoDB agar fitur transaction tersedia dan berfungsi sesuai properti ACID.