Today I Learned: Apa Yang Terjadi, Ketika Transaction Database Belum Di-commit?
Zakiego
@zakiego
Latar Belakang
Dimulai dari rasa penasaran, bagaimana sebenarnya transaction
pada database bekerja, kemudian muncul sebuah pertanyaan.
Jika ada si A dan B yang terkoneksi ke database yang sama, kemudian A melakukan transaction
, tetapi belum selesai, apakah B akan tertahan?
Setup
Database yang digunakan PostgreSQL dengan versi 16.2.
Didirikan di atas Docker dengan command:
docker run --name transaction_lab -e POSTGRES_PASSWORD=mysecretpassword -d postgres
Kemudian masuk ke terminalnya menggunakan command:
docker exec -it transaction_lab psql -U postgres
Pengujian Pertama
Pengujian ini untuk menjawab, apakah user B masih bisa melakukan query SELECT
, saat user A melakukan BEGIN TRANSACTION
?
Skema yang akan dilakukan adalah:
- User A dan user B terhubung ke Database
- User A menjalankan
BEGIN TRANSACTION
- User A menjalankan
UPDATE
(belum di-commit) - User B menjalankan
SELECT
- User A menjalankan
COMMIT
- User B menjalankan
SELECT
(lagi)
Berikut hasilnya:
Awalnya nama Presiden adalah "Avatar".
Kemudian user A melakukan BEGIN TRANSACTION
(2) dan melakukan UPDATE
(3) terhadap nama Presiden menjadi "Zuko".
Di saat jeda tersebut, user B melakukan SELECT
(4) untuk mengecek nama Presiden. Ternyata nama Presiden masih "Avatar"
Setelah user A menyelesaikan transaksinya dengan menjalankan COMMIT
(5), maka saat user B menjalankan SELECT
(6) sekali lagi, barulah nama Presiden berubah menjadi "Zuko".
Sehingga, kesimpulan (CMIIW) dari percobaan ini adalah, saat satu user melakukan TRANSACTION
, user lain masih bisa melakukan query SELECT
, namun data yang didapat adalah yang belum ter-update, karena pelaku utama belum melakukan COMMIT
terhadap update-nya.
Pengujian Kedua
Jika pada pengujian pertama, user B hanya melakukan read atau SELECT
, maka di pengujian kali ini, akan kita coba mereka berdua untuk melakukan UPDATE
pada yang sama.
- User A dan user B terhubung ke Database
- User A menjalankan
SELECT
- User A menjalankan
BEGIN TRANSACTION
- User A menjalankan
UPDATE
diid = 1
(belum di-commit) - User B menjalankan
UPDATE
tanpaTRANSACTION
padaid = 1
juga - User A menjalankan
COMMIT
- User A menjalankan
SELECT
(lagi)
Berikut hasilnya:
Saat dilakukan pengecekan awal, nama Presiden adalah "Avatar". Kemudian user A memulai TRANSACTION
(3) dan melakukan update nama Presiden menjadi "Zuko" (4). Namun user A belum melakukan COMMIT
.
Setelah itu datang user B, ia mencoba melakukan UPDATE
nama Presiden menjadi "Katara". (5) Apa yang terjadi? Ternyata user B menjadi menunggu. Tidak ada response yang ia terima.
Saat user A melakukan COMMIT
(6), seketika itu pula UPDATE
yang dilakukan user B berjalan.
Hasilnya ialah, nama Presiden menjadi "Katara".
Sehingga, kesimpulan (CMIIW) dari percobaan ini adalah saat user A melakukan TRANSACTION
pada satu baris data, kemudian datang user B yang ingin mengedit data yang sama, maka user B akan tertahan. Sampai kapan? Sampai user A menyelesaikan transaksinya. Saat user A telah menyelesaikan transaksinya, maka selanjutnya perintah user B yang dijalankan. Sehingga, data akhir adalah perubahan yang dilakukan user B.
Penutup
Percobaan ini hanya didasari karena rasa penasaran. Dalam kasus yang lebih kompleks, mungkin hasilnya akan berbeda. Terakhir, saya bukan seorang backend engineer, sebab itulah saya mencoba belajar dengan melakukan percobaan ini.