Getting started with Transaction Control (TCL)
Hai semuanya, sekarang kita akan membahas tentang Transaction Language Control atau singkatanya TCL, dimana transaction control ini adalah salah satu feature di Relational Database Management System (RDBMS) yang secara umum digunakan untuk mengelompokan sekumpulan query yang akan dikirimkan ke database server secara atomic, consistent, isolated dan durable.
Untuk lebih jelasnya, yuk kita bahas secara lebih detail. Adapun materi yang akan kita bahas kali ini adalah
- Default Transaction Control behavior
- Using Commit clause
- Using Rollback clause
- Using Savepoint clause
Ok tanpa berlama-lama yuk langsung aja kita bahas materi yang pertama:
Default Transaction Control behavior
A PostgreSQL transaction is atomic, consistent, isolated, and durable. These properties are often referred to as ACID:
- Atomicity guarantees that the transaction completes in an all-or-nothing manner.
- Consistency ensures the change to data written to the database must be valid and follow predefined rules.
- Isolation determines how transaction integrity is visible to other transactions.
- Durability makes sure that transactions that have been committed will be stored in the database permanently.
By default PostgreSQL using auto-commit every single query executed by database atau setiap 1 query yang kita jalankan di database server PostgreSQL maka akan automatis di commit. Seperti berikut contohnya:
Ketika di execute, maka secara default data akan bertambah ke dalam tabel dan simpan secara permanent. Tetapi jika kita ingin merubah behavior menjadi manual, kita perlu menggunakan keywork BEGIN
pada awal statement.
Syntaxnya seperti berikut
Berikut adalah implementasi penggunakan manual transaction:
Jika kita execute, maka hasilnya seperti berikut:
database/postgres-14 [master●] » psql -U hr
psql (14.6)
Type "help" for help.
hr= begin;
BEGIN
hr=* insert into regions(region_id, region_name)
hr-* values (7, 'Other 2');
INSERT 0 1
hr=* select * from regions where region_id = 7;
region_id | region_name
-----------+-------------
7 | Other 2
(1 row)
hr=* exit
database/postgres-14 [master●] » psql -U hr
psql (14.6)
Type "help" for help.
hr= select * from regions where region_id = 7;
region_id | region_name
-----------+-------------
(0 rows)
hr=#
Nah terlihat hasilnya ketika query di execute, maka secara temporary data akan tersimpan ke tabel tetapi begitu session habis atau kita keluar dari session tersebut, maka datanya akan hilang.
Using Commit clause
Perintah commit
digunakan untuk menyimpan perubahan yang dilakukan oleh perintah Data Manipulation secara permanent di database, Seperti pada section sebelumnya jika kita tidak menggunakan perintah commit
di akhir statement maka data akan hilang jika kita hapus session connection.
Perintah commit
hanya bisa dilakukan jika diawali dengan menggunakan begin
clause, tanpa perintah begin
atau jika tidak memiliki transaction dalamnya maka, akan muncul warning there is no transaction in progress
Syntaxnya seperti berikut:
Implementasinya seperti berikut:
Jika dijalankan hasilnya seperti berikut:
database/postgres-14 [master●] » psql -U hr
psql (14.6)
Type "help" for help.
hr= BEGIN;
BEGIN
hr=* INSERT INTO regions(region_id, region_name)
hr-* VALUES (7, 'Other 2');
INSERT 0 1
hr=* COMMIT;
COMMIT
hr= select * from regions where region_id = 7;
region_id | region_name
-----------+-------------
7 | Other 2
(1 row)
hr= exit
database/postgres-14 [master●] » psql -U hr
psql (14.6)
Type "help" for help.
hr= select * from regions where region_id = 7;
region_id | region_name
-----------+-------------
7 | Other 2
(1 row)
Nah jadi bisa kita perhatihan dari output diatas, meskipun kita close session connect data masih tersimpan di table regions
tersebut karena kita sudah menggunakan perintah commit
.
Using Rollback clause
Perintah rollback
digunakan untuk membatalkan transaksi yang sedang aktif untuk mengembalikan ke last state commit pada database. Sama halnya dengan perintah commit
perintah rollback
tidak akan berjalan jika tanpa begin
atau transaction sedang tidak aktif.
NOTES: Jika perintah commit
sudah di execute kita tidak bisa mengembalikannya, perintah rollback
hanya bisa mengembalikan perubahan ketika belum di commit
.
Syntaxnya seperti berikut:
Perintah rollback ini biasanya digunakan jika terjadi kesalahan baik dari human error, system error maupun runtime error diataranya:
- Salah input value pada data manipulation
- Error pada constraint (unique, foreign key, check)
Contoh implementasinya seperti berikut:
Jika dijalnakan maka outputnya seperti bertikut:
hr= BEGIN;
BEGIN
hr=* UPDATE regions set region_name = 'Other 3'
hr-* WHERE region_id = 7;
UPDATE 1
hr=* SELECT * FROM regions WHERE region_id = 7;
region_id | region_name
-----------+-------------
7 | Other 3
(1 row)
hr=* ROLLBACK;
ROLLBACK
hr= SELECT * FROM regions WHERE region_id = 7;
region_id | region_name
-----------+-------------
7 | Other 2
(1 row)
Nah jadi kita perhatikan pada output diatas, ketika kita jalankan perintah update
dan juga select
data sudah berubah di tabel begitu di rollback maka data akan kembali ke last update sebelumnya.
Using Savepoint clause
Perintah savepoint
secara fungsi mirip seperti di game-game balapan yaitu checkpoint dimana jika kita melintas pada check point tersebut maka game akan tersimpan jika ada crash/tabrakan maka game tidak akan mengulang dari awal lagi tetapi dari last savepoint terkahir. Pada kenyataannya perintah savepoint
ini akan berguna jika kita memiliki banyak query dalam suatu transaksi seperti berikut:
So A savepoint is a special mark inside a transaction that allows all commands that are executed after it was established to be rolled back, restoring the transaction state to what it was at the time of the savepoint.
Syntax seperti berikut
Implementasinya seperti berikut:
Jika dijalankan maka outputnya seperti berikut:
hr= BEGIN;
BEGIN
hr=* INSERT INTO regions(region_id, region_name)
hr-* VALUES (8, 'Other 3');
INSERT 0 1
hr=* UPDATE regions
hr-* set region_name = 'Other 3'
hr-* WHERE region_id = 7;
UPDATE 1
hr=* SELECT * FROM regions WHERE region_id in (7, 8);
region_id | region_name
-----------+-------------
7 | Other 3
8 | Other 3
(2 rows)
hr=* SAVEPOINT trx_1;
SAVEPOINT
hr=* UPDATE regions
hr-* set region_name = 'Other 4'
hr-* WHERE region_id = 7;
UPDATE 1
hr=* INSERT INTO regions(region_id, region_name)
hr-* VALUES (8, 'Other 3');
ERROR: duplicate key value violates unique constraint "regions_pkey"
DETAIL: Key (region_id)=(8) already exists.
hr=! SELECT * FROM regions WHERE region_id in (7, 8);
ERROR: current transaction is aborted, commands ignored until end of transaction block
hr=! ROLLBACK TO SAVEPOINT trx_1;
ROLLBACK
hr=* SELECT * FROM regions WHERE region_id in (7, 8);
region_id | region_name
-----------+-------------
7 | Other 3
8 | Other 3
(2 rows)
hr=* COMMIT;
COMMIT
Nah jadi kita kita lihat dari output tersebut, sesuai harapan kita kita bisa rollback ke terakhir savepoint jadi kita tidak harus melakukan task dari awal lagi.