Locking

Locking #

Database locking adalah salah satu mekanisme paling fundamental dalam sistem database relasional untuk menjaga konsistensi data saat banyak transaksi berjalan secara bersamaan (concurrent transactions). Tanpa locking, database akan sangat rentan terhadap race condition, data corruption, dan hasil query yang tidak dapat diprediksi.

Namun di sisi lain, locking yang tidak dipahami atau digunakan secara keliru justru bisa menjadi sumber bottleneck terbesar: query melambat, connection menumpuk, throughput turun, bahkan sistem terlihat seperti “hang”.

Artikel ini akan membahas secara lengkap dan praktis:

  • Apa itu database locking
  • Masalah apa yang ingin diselesaikan
  • Jenis-jenis locking
  • Level locking
  • Hubungan locking dengan isolation level
  • Dampak buruk locking yang salah
  • Best practice menggunakan locking secara aman dan efisien

Apa Itu Database Locking? #

Database locking adalah mekanisme kontrol konkurensi (concurrency control) yang digunakan untuk mencegah beberapa transaksi mengakses atau memodifikasi data yang sama secara bersamaan dengan cara yang tidak aman.

Secara sederhana:

  • Saat sebuah transaksi membaca atau menulis data
  • Database dapat “mengunci” data tersebut
  • Transaksi lain harus menunggu, diblok, atau dibatasi aksesnya

Tujuannya adalah menjaga prinsip ACID, terutama:

  • Isolation: transaksi seolah-olah berjalan sendiri
  • Consistency: data selalu berada pada state yang valid

Masalah Tanpa Locking (Anomali Transaksi) #

Tanpa mekanisme locking yang tepat, database bisa mengalami anomali berikut:

Dirty Read #

Transaksi membaca data yang belum di-commit oleh transaksi lain.

Non-repeatable Read #

Transaksi membaca data yang sama dua kali, tetapi hasilnya berbeda karena transaksi lain melakukan update di tengah.

Phantom Read #

Transaksi membaca sekumpulan row, lalu transaksi lain menambah row baru yang ikut terbaca di query berikutnya.

Locking hadir untuk mengontrol perilaku ini.


Jenis-Jenis Database Locking #

Shared Lock (S Lock / Read Lock) #

Digunakan saat transaksi membaca data.

Karakteristik:

  • Banyak transaksi boleh memiliki shared lock secara bersamaan
  • Transaksi lain tidak boleh menulis data yang sama

Contoh:

SELECT * FROM orders WHERE id = 10 LOCK IN SHARE MODE;

Use case:

  • Laporan
  • Validasi data sebelum update

Exclusive Lock (X Lock / Write Lock) #

Digunakan saat transaksi menulis (INSERT / UPDATE / DELETE).

Karakteristik:

  • Hanya satu transaksi yang boleh memegang lock
  • Transaksi lain tidak boleh membaca atau menulis

Contoh:

SELECT * FROM orders WHERE id = 10 FOR UPDATE;

Intent Lock #

Digunakan oleh database engine (misalnya InnoDB) untuk menandai niat mengunci level yang lebih rendah.

Jenis:

  • Intent Shared (IS)
  • Intent Exclusive (IX)

Tujuan:

  • Optimasi hierarchical locking
  • Menghindari scanning lock berlebihan

Biasanya tidak diakses langsung oleh developer, tapi penting dipahami saat debugging deadlock.

Row-Level Lock #

Lock diterapkan per baris (row).

Kelebihan:

  • Concurrency tinggi
  • Transaksi lain masih bisa mengakses row lain

Kekurangan:

  • Overhead lebih besar

Digunakan oleh engine seperti InnoDB.

Table-Level Lock #

Lock diterapkan ke seluruh tabel.

Kelebihan:

  • Implementasi sederhana
  • Cocok untuk bulk operation tertentu

Kekurangan:

  • Concurrency sangat rendah

Contoh:

LOCK TABLE orders WRITE;

Gap Lock #

Mengunci rentang nilai index, bukan row tertentu.

Tujuan:

  • Mencegah phantom read

Contoh:

SELECT * FROM orders WHERE id BETWEEN 10 AND 20 FOR UPDATE;

Gap lock sering menjadi sumber kebingungan karena:

  • Mengunci data yang “tidak terlihat”
  • Bisa memblok INSERT

Next-Key Lock #

Kombinasi:

  • Row lock + gap lock

Digunakan oleh InnoDB pada isolation level REPEATABLE READ.

Tujuan:

  • Menjamin konsistensi range query

Locking dan Isolation Level #

Isolation level menentukan seberapa agresif database melakukan locking.

Isolation LevelLocking Behavior
READ UNCOMMITTEDHampir tidak ada lock
READ COMMITTEDLock dilepas setelah read
REPEATABLE READRow + gap lock
SERIALIZABLESemua read jadi locking read

Catatan penting:

  • Isolation level tinggi ≠ selalu lebih baik
  • Isolation tinggi = locking lebih agresif = potensi blocking

Dampak Buruk Locking yang Tidak Tepat #

Long Transaction #

Transaksi lama = lock dipegang lama = sistem melambat.

Lock Contention #

Banyak transaksi berebut lock yang sama.

Deadlock #

Dua transaksi saling menunggu lock satu sama lain.

Throughput Turun #

CPU idle tapi database lambat karena menunggu lock.


Best Practice Menggunakan Database Locking #

Jaga Transaksi Sesingkat Mungkin #

Golden rule:

Semakin singkat transaksi, semakin sehat database.

Hindari:

  • Logic bisnis panjang di dalam transaction
  • Call API eksternal di dalam transaction

Lock Saat Benar-Benar Dibutuhkan #

Jangan gunakan FOR UPDATE secara default.

Gunakan hanya jika:

  • Data akan di-update
  • Harus menjamin idempotency
  • Ada race condition nyata

Selalu Gunakan Index yang Tepat #

Lock tanpa index bisa berubah menjadi:

  • Table lock
  • Lock range yang besar

Pastikan:

  • Kolom di WHERE clause ter-index

Hindari Range Lock Jika Tidak Perlu #

Range query + FOR UPDATE = gap lock.

Jika memungkinkan:

  • Lock by primary key
  • Gunakan equality (=) bukan range

Konsisten Urutan Akses Data #

Untuk menghindari deadlock:

  • Akses tabel dan row dalam urutan yang sama
  • Jangan acak urutan update

Gunakan Optimistic Lock Jika Cocok #

Untuk data yang jarang konflik:

  • Version column
  • Compare-and-swap

Lebih scalable dibanding pessimistic lock.

Monitor dan Observability #

Pantau:

  • Slow query karena lock
  • Deadlock log
  • Transaction duration

Gunakan:

  • SHOW ENGINE INNODB STATUS
  • Performance schema

Kapan Locking Sangat Dibutuhkan? #

Locking sangat penting pada kasus:

  • Financial transaction
  • Inventory / stock
  • Status processing (order, payment, job)
  • Idempotency HTTP request

Namun locking bukan solusi default untuk semua masalah concurrency.


Penutup #

Database locking adalah pedang bermata dua:

  • Digunakan dengan benar → data konsisten dan sistem aman
  • Digunakan sembarangan → database lambat dan sulit diskalakan

Developer yang matang bukan yang menghindari locking sama sekali, tapi yang:

  • Memahami cara kerjanya
  • Tahu kapan harus menggunakannya
  • Tahu kapan harus menghindarinya

Dengan pemahaman yang tepat, locking akan menjadi alat proteksi, bukan sumber masalah.

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact