Transaction dan ACID dalam MySQL

Dalam sistem database, transaksi (transaction) adalah serangkaian operasi yang dieksekusi sebagai satu kesatuan logis. Jika transaksi berhasil, semua perubahan yang dilakukan akan disimpan dalam database (COMMIT). Namun, jika terjadi kegagalan, perubahan yang telah dilakukan dapat dibatalkan (ROLLBACK) sehingga database tetap konsisten.
Agar transaksi berjalan dengan aman dan andal, MySQL menerapkan konsep ACID (Atomicity, Consistency, Isolation, Durability). Artikel ini akan membahas pengertian transaksi, prinsip ACID, serta bagaimana cara menggunakannya dalam MySQL.
Apa Itu Transaction di MySQL?
Transaction adalah kumpulan satu atau lebih pernyataan SQL yang dieksekusi secara atomik. Transaksi digunakan untuk memastikan keakuratan dan konsistensi data, terutama dalam sistem yang menangani banyak operasi secara bersamaan, seperti perbankan dan e-commerce.
Contoh Kasus Penggunaan Transaction:
Bayangkan Anda melakukan transfer uang dari akun A ke akun B. Proses ini memerlukan dua langkah:
- Mengurangi saldo dari akun A.
- Menambah saldo ke akun B.
Jika salah satu langkah gagal (misalnya karena koneksi terputus), transaksi harus dibatalkan untuk mencegah kesalahan saldo.
Prinsip ACID dalam Transaksi
Agar transaksi dapat berjalan dengan aman, MySQL mengikuti standar ACID yang terdiri dari:
1. Atomicity (Atomisitas)
- Transaksi harus bersifat “all or nothing” (berjalan sepenuhnya atau tidak sama sekali).
- Jika salah satu perintah dalam transaksi gagal, maka semua perubahan harus dibatalkan (ROLLBACK).
- Contoh: Jika transfer saldo dari akun A ke akun B gagal, maka saldo akun A tidak boleh berkurang.
2. Consistency (Konsistensi)
- Database harus selalu dalam keadaan konsisten sebelum dan sesudah transaksi.
- Contoh: Jika sebuah transaksi memindahkan saldo dari satu akun ke akun lain, total saldo keseluruhan harus tetap sama.
3. Isolation (Isolasi)
- Transaksi yang berjalan secara bersamaan tidak boleh saling mengganggu atau menyebabkan ketidakakuratan data.
- MySQL memiliki Isolation Levels untuk mengatur bagaimana transaksi diproses secara bersamaan.
4. Durability (Daya Tahan)
- Setelah transaksi dikonfirmasi (COMMIT), perubahan harus disimpan secara permanen dalam database, meskipun terjadi kegagalan sistem.
- Data harus tetap ada bahkan setelah server MySQL mengalami crash atau restart.
Cara Menggunakan Transaction di MySQL
Secara default, MySQL menjalankan pernyataan SQL secara langsung tanpa transaksi. Untuk menggunakan transaksi, kita harus menulisnya secara eksplisit menggunakan START TRANSACTION, COMMIT, dan ROLLBACK.
Sintaks Dasar Transaction
START TRANSACTION; -- Memulai transaksi
-- Perintah SQL
COMMIT; -- Menyimpan perubahan jika semua berhasil
Atau, jika terjadi kesalahan:
START TRANSACTION;
-- Perintah SQL
ROLLBACK; -- Membatalkan transaksi jika ada kesalahan
Contoh Transaksi Sederhana
Misalkan kita memiliki tabel accounts
dengan struktur berikut:
CREATE TABLE accounts (
id INT PRIMARY KEY,
name VARCHAR(100),
balance DECIMAL(10,2)
);
Dan terdapat data awal:
INSERT INTO accounts (id, name, balance) VALUES
(1, 'Alice', 1000.00),
(2, 'Bob', 500.00);
Contoh: Transfer Saldo dengan Transaksi
START TRANSACTION;
-- Mengurangi saldo Alice
UPDATE accounts SET balance = balance - 200 WHERE id = 1;
-- Menambahkan saldo Bob
UPDATE accounts SET balance = balance + 200 WHERE id = 2;
-- Jika semua perintah berhasil, simpan perubahan
COMMIT;
Jika terjadi kesalahan di tengah proses, kita dapat membatalkan transaksi:
START TRANSACTION;
UPDATE accounts SET balance = balance – 200 WHERE id = 1;
-- Simulasi kesalahan
-- UPDATE accounts SET balance = balance + 200 WHERE id = 999; -- ID tidak ada
-- Jika terjadi kesalahan, rollback transaksi
ROLLBACK;
Isolation Levels dalam MySQL
Isolation Level menentukan bagaimana transaksi satu dengan yang lain berinteraksi. MySQL memiliki 4 isolation level utama:
Isolation Level | Deskripsi | Masalah yang dapat terjadi |
READ UNCOMMITTED | Transaksi bisa membaca perubahan yang belum dikonfirmasi oleh transaksi lain. | Dirty Read (Membaca data yang belum di-COMMIT) |
READ COMMITTED | Hanya membaca data yang telah dikonfirmasi oleh transaksi lain. | Non-repeatable Read (Data berubah karena transaksi lain melakukan UPDATE/DELETE) |
REPEATABLE READ (Default MySQL) | Membaca data yang sama dalam transaksi, bahkan jika transaksi lain mengubahnya. | Phantom Read ( Jumlah baris berubah karena transaksi lain melakukan INSERT/DELETE) |
SERIALIZABLE | Eksekusi transaksi dilakukan secara berurutan untuk memastikan keamanan maksimal. | Tidak ada, tetapi lambat |
Untuk mengatur Isolation Level:
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
Penjelasan Masalah
Dirty Read
Terjadi ketika suatu transaksi membaca data yang telah dimodifikasi oleh transaksi lain tetapi belum dikonfirmasi (COMMIT). Jika transaksi pertama melakukan ROLLBACK, maka transaksi kedua telah membaca data yang sebenarnya tidak pernah ada secara resmi.
Contoh Dirty Read
Misalkan kita memiliki tabel accounts
:
CREATE TABLE accounts (
id INT PRIMARY KEY,
name VARCHAR(100),
balance DECIMAL(10,2)
);
INSERT INTO accounts (id, name, balance) VALUES (1, 'Alice', 1000.00);
Langkah 1: Transaksi Pertama Memodifikasi Data tetapi Belum Commit
START TRANSACTION;
UPDATE accounts SET balance = 500 WHERE id = 1;
-- Transaksi ini belum di-COMMIT
Transaksi Kedua Membaca Data yang Belum Commit (Dirty Read)
SELECT balance FROM accounts WHERE id = 1; -- Hasil: 500
Transaksi Pertama Membatalkan Perubahan, dan Transaksi Kedua Membaca Data Lagi
SELECT balance FROM accounts WHERE id = 1; -- Hasil: 1000
Sehingga transaksi kedua sempat membaca data yang tidak valid.
Non-Repeatable Read
Terjadi ketika dalam satu transaksi, data yang dibaca pada waktu yang berbeda berubah karena transaksi lain melakukan UPDATE atau DELETE.
Contoh Non-Repeatable Read
Transaksi Pertama Membaca Data
START TRANSACTION;
SELECT balance FROM accounts WHERE id = 1; -- Hasil: 1000
Transaksi Kedua Memodifikasi Data dan Commit
START TRANSACTION;
UPDATE accounts SET balance = 500 WHERE id = 1;
COMMIT;
Transaksi Pertama Membaca Ulang Data
SELECT balance FROM accounts WHERE id = 1; -- Hasil: 500
Karena ada perubahan dari transaksi kedua, hasil pembacaan dalam satu transaksi yang sama menjadi tidak konsisten.
Phantom Read
Terjadi ketika dalam satu transaksi, jumlah baris yang diambil berubah karena transaksi lain melakukan INSERT atau DELETE.
Contoh Phantom Read
Transaksi Pertama Mengambil Semua Data
START TRANSACTION;
SELECT * FROM accounts;
Misalkan hasilnya ada 1 baris:
+----+-------+---------+
| id | name | balance |
+----+-------+---------+
| 1 | Alice | 1000 |
+----+-------+---------+
Transaksi Kedua Menambahkan Data Baru dan Commit
START TRANSACTION;
INSERT INTO accounts (id, name, balance) VALUES (2, 'Bob', 2000);
COMMIT;
Transaksi Pertama Mengambil Data Lagi
SELECT * FROM accounts;
Hasilnya sekarang ada 2 baris:
+----+-------+---------+
| id | name | balance |
+----+-------+---------+
| 1 | Alice | 1000 |
| 2 | Bob | 2000 |
+----+-------+---------+
Jumlah baris berubah meskipun transaksi pertama masih berlangsung.
Keuntungan Menggunakan Transaction di MySQL
✅ Keamanan Data – Mencegah perubahan yang tidak lengkap atau salah dalam database.
✅ Konsistensi Data – Memastikan data tetap dalam keadaan yang valid.
✅ Menghindari Korupsi Data – Transaksi membantu menghindari data yang rusak akibat kesalahan sistem atau kegagalan eksekusi query.
✅ Kontrol Akses Bersamaan – Mencegah konflik dalam pengolahan data saat ada banyak pengguna yang mengakses database secara bersamaan.
Kesimpulan
- Transaction adalah fitur MySQL yang memungkinkan eksekusi beberapa query sebagai satu kesatuan yang atomik.
- ACID memastikan bahwa transaksi dilakukan dengan aman dan konsisten.
- COMMIT digunakan untuk menyimpan perubahan, sementara ROLLBACK untuk membatalkan perubahan jika terjadi kesalahan.
- Isolation Levels mengontrol bagaimana transaksi dapat mengakses data yang sedang diubah oleh transaksi lain.