{Kurung Kurawal}

MySQL Transaction Query

Dalam SQL terkadang kita membutuhkan untuk menjalankan lebih dari 1 query untuk mendapatkan hasil tertentu. Dimana beberapa query ini adalah menjadi 1 kebutuhan. Contohnya, dalam proses transfer saldo dari rekening A ke rekening B. Proses transfer ini melibatkan paling tidak 2 buah query, yaitu query pertama mengurangi jumlah saldo A dan query kedua menambahkan saldo rekening B.

Hal seperti ini disebut sebagai atomic transaction, atomic berarti bagian terkecil yang sudah tidak dapat dipisahkan lagi. 2 buah query yang dibutuhkan untuk proses pemindahan saldo itu harus berjalan secara menyeluruh, bayangkan ketika proses pemotongan saldo A berhasil, namun penambahan saldo B gagal, pasti si A marah besar, hehehe….

Secara gampangnya, saldo A harus terpotong apabila saldo B berhasil ditambahkan, atau query pertama akan disimpan apabila query kedua (dan seterusnya) berhasil. Jika tidak, maka perubahan yang terjadi harus dibatalkan. Perubahan disini bukan berarti menambahkan kembali ke rekening A, melainkan membatalkan perubahan yang ada.

Query untuk menjalankan hal ini disebut sebagai TRANSACTION. Hasil dari Transaction ini akan disimpan bila seluruh query yang terlibat berhasil dijalankan. di MySQL, Transaction harus dimulai dengan query BEGIN, kemudian diakhiri dengan COMMIT apabila ingin menyimpan perubahan, dan ROLLBACK apabila ingin membatalkan perubahan yang terjadi setelah BEGIN tadi.

Contoh penerapan dalam MySQL (dan juga database SQL standard lainnya) adalah berikut

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
mysql> DESC customer;
+-------+-------------+------+-----+---------+----------------+
| FIELD | TYPE        | NULL | KEY | DEFAULT | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | INT(11)     | NO   | PRI | NULL    | AUTO_INCREMENT |
| name  | VARCHAR(40) | YES  |     | NULL    |                |
| saldo | INT(11)     | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
3 ROWS IN SET (0.00 sec)
 
mysql> SELECT * FROM customer;
+----+------------+-------+
| id | name       | saldo |
+----+------------+-------+
|  1 | John Doe   |   100 |
|  2 | Will Smith |   100 |
+----+------------+-------+
2 ROWS IN SET (0.00 sec)
 
mysql> BEGIN;
Query OK, 0 ROWS affected (0.01 sec)
 
mysql> UPDATE customer SET saldo = saldo - 20 WHERE id = 1;
Query OK, 1 ROW affected (0.00 sec)
ROWS matched: 1  Changed: 1  Warnings: 0
 
mysql> SELECT * FROM customer;
+----+------------+-------+
| id | name       | saldo |
+----+------------+-------+
|  1 | John Doe   |    80 |
|  2 | Will Smith |   100 |
+----+------------+-------+
2 ROWS IN SET (0.00 sec)
 
mysql> ROLLBACK;
Query OK, 0 ROWS affected (0.10 sec)
 
mysql> SELECT * FROM customer;
+----+------------+-------+
| id | name       | saldo |
+----+------------+-------+
|  1 | John Doe   |   100 |
|  2 | Will Smith |   100 |
+----+------------+-------+
2 ROWS IN SET (0.00 sec)

Contoh query diatas memberikan gambaran ketika saldo customer 1 diubah, namun kemudian dilakukan perintah ROLLBACK. Data yang ada akan dikembalikan sama seperti keadaan sebelum BEGIN.

Berikut contoh penerapan COMMIT.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
mysql> SELECT * FROM customer;
+----+------------+-------+
| id | name       | saldo |
+----+------------+-------+
|  1 | John Doe   |   100 |
|  2 | Will Smith |   100 |
+----+------------+-------+
2 ROWS IN SET (0.01 sec)
 
mysql> BEGIN;
Query OK, 0 ROWS affected (0.00 sec)
 
mysql> UPDATE customer SET saldo = saldo - 30 WHERE id = 1;
Query OK, 1 ROW affected (0.00 sec)
ROWS matched: 1  Changed: 1  Warnings: 0
 
mysql> SELECT * FROM customer;
+----+------------+-------+
| id | name       | saldo |
+----+------------+-------+
|  1 | John Doe   |    70 |
|  2 | Will Smith |   100 |
+----+------------+-------+
2 ROWS IN SET (0.00 sec)
 
mysql> COMMIT;
Query OK, 0 ROWS affected (0.05 sec)
 
mysql> SELECT * FROM customer;
+----+------------+-------+
| id | name       | saldo |
+----+------------+-------+
|  1 | John Doe   |    70 |
|  2 | Will Smith |   100 |
+----+------------+-------+
2 ROWS IN SET (0.00 sec)
 
mysql> BEGIN;
Query OK, 0 ROWS affected (0.00 sec)
 
mysql> UPDATE customer SET saldo = saldo - 20;
Query OK, 2 ROWS affected (0.01 sec)
ROWS matched: 2  Changed: 2  Warnings: 0
 
mysql> SELECT * FROM customer;
+----+------------+-------+
| id | name       | saldo |
+----+------------+-------+
|  1 | John Doe   |    50 |
|  2 | Will Smith |    80 |
+----+------------+-------+
2 ROWS IN SET (0.00 sec)
 
mysql> ROLLBACK;
Query OK, 0 ROWS affected (0.18 sec)
 
mysql> SELECT * FROM customer;
+----+------------+-------+
| id | name       | saldo |
+----+------------+-------+
|  1 | John Doe   |    70 |
|  2 | Will Smith |   100 |
+----+------------+-------+
2 ROWS IN SET (0.00 sec)

Pada tampilan diatas,apa yang terjadi adalah
1. Saldo awal adalah 100
2. BEGIN, kita mulai SQL Transaction
3. Kita kurangi saldo customer dengan 1 sebanyak 30
4. Saldo customer 1 adalah 70
5. COMMIT, simpan perubahan secara permanen
6. Saldo customer 1 adalah 70, setelah commit secara permanen
7. BEGIN, kita mulai SQL Transaction kedua
8. Kurangi kembali saldo customer 1 sebanyak 20
9. Lihat bahwa saldo customer 1 adalah 50, yang mana adalah benar 70 – 20 = 50;
10. kita lakukan ROLLBACK, batalkan seluruh perubahan setelah BEGIN
11. Saldo customer 1 kembali menjadi 70.

Demikian tulisan sederhana ini, semoga bermanfaat bagi kita semua.