RESTForge

Distributed Lock

Penguncian per-record untuk mencegah konflik penulisan bersamaan

Distributed Lock adalah mekanisme koordinasi antar worker process yang berjalan di cluster mode. Fitur ini menggunakan Redis sebagai backend dan dirancang untuk mengatasi race condition pada operasi WRITE terhadap record yang sama. Lock bersifat per-record sehingga operasi pada record yang berbeda tetap berjalan paralel.

Referensi Cepat (Quick Reference)

PropertiNilai
DependencyRedis Server
AktivasiLOCK_DISTRIBUTED_ENABLED=true di file .env
Lock otomatisupdateData() dan deleteData() (per-record WRITE lock)
Strategiretry (default, exponential backoff) atau reject (immediate fail)
Default TTL10 detik
Tanpa lockaddData() (INSERT membuat row baru) dan operasi READ

Masalah yang Diselesaikan (Problem Statement)

Tanpa Distributed Lock:
  Worker 1 → UPDATE supplier id='abc' SET nama='PT A' ─┐
  Worker 2 → UPDATE supplier id='abc' SET nama='PT B' ─┘→ Hasil tidak konsisten

Dengan Distributed Lock (per-record):
  Worker 1 → Lock(abc) → UPDATE → Release
  Worker 2 → Tunggu Lock(abc) ─────────→ Lock acquired → UPDATE → Release

Lock bersifat per-record sehingga operasi pada record berbeda berjalan paralel tanpa saling memblokir:

Worker 1 → UPDATE supplier id='abc' → Lock(abc) → Berjalan paralel
Worker 2 → UPDATE supplier id='xyz' → Lock(xyz) → Berjalan paralel
Worker 3 → UPDATE supplier id='abc' → Lock(abc) → Tunggu Worker 1 selesai

Konfigurasi (Configuration)

config/production.env
LOCK_DISTRIBUTED_ENABLED=true
LOCK_DISTRIBUTED_STRATEGY=retry
LOCK_DISTRIBUTED_TTL=10
LOCK_DISTRIBUTED_RETRY=3
LOCK_DISTRIBUTED_RETRY_DELAY=100
ParameterDefaultKeterangan
LOCK_DISTRIBUTED_ENABLEDfalseMengaktifkan fitur distributed lock
LOCK_DISTRIBUTED_STRATEGYretryretry (exponential backoff) atau reject (immediate fail)
LOCK_DISTRIBUTED_TTL10Durasi maksimal lock aktif (detik) sebelum expire otomatis
LOCK_DISTRIBUTED_RETRY3Jumlah percobaan acquire lock (hanya untuk strategy retry)
LOCK_DISTRIBUTED_RETRY_DELAY100Delay awal antar retry dalam ms (hanya untuk strategy retry)

Strategi Lock (Lock Strategies)

Strategy: retry (Default)

Request menunggu dengan exponential backoff sampai lock tersedia atau timeout tercapai. Delay antar percobaan: RETRY_DELAY * 2^attempt (default: 100ms, 200ms, 400ms).

Worker A → Lock(abc) acquired → UPDATE → Release
Worker B → Lock(abc) wait 100ms → wait 200ms → Lock acquired → UPDATE → Release
Worker C → Lock(abc) wait 100ms → wait 200ms → wait 400ms → TIMEOUT ERROR

Strategy: reject

Request langsung ditolak jika lock tidak tersedia, tanpa menunggu. Parameter RETRY dan RETRY_DELAY diabaikan.

Worker A → Lock(abc) SET NX → OK   → UPDATE → Release
Worker B → Lock(abc) SET NX → FAIL → IMMEDIATE ERROR

Perbandingan Strategi (Strategy Comparison)

Aspekretryreject
Saat lock tidak tersediaMenunggu dan coba lagiLangsung error
Latensi request keduaBertambah (waktu tunggu)Tidak ada (langsung error)
Client handlingTidak perlu retry logicPerlu retry logic di client
Cocok untukFrontend/UI, operasi pentingSistem otomatis dengan retry logic sendiri

Operasi yang Dilindungi (Protected Operations)

MethodLockAlasan
updateData()WRITE lock per-record, melindungi concurrent update
deleteData()WRITE lock per-record, melindungi concurrent update+delete
addData()INSERT membuat row baru, tidak ada konflik pada record yang sama
getDatatables()Operasi READ, database MVCC menjamin read consistency

Format Lock Key

rf:lock:{project}:{endpoint}:{recordId}:write

Contoh: rf:lock:mini-inventory:supplier:550e8400-...:write

Distributed lock dan cache layer adalah dua fitur yang independen. Keduanya menggunakan Redis sebagai backend, tetapi tidak saling bergantung. Lock dapat aktif tanpa cache, dan sebaliknya.

Langkah Selanjutnya (Next Steps)

  • Cache untuk layer caching berbasis Redis
  • Idempotency untuk proteksi duplikasi request
  • Rate Limit untuk pembatasan jumlah request

On this page