0Pricing
SQL Academy · Pelajaran

Deadlock: Deteksi dan Pencegahan

Pahami bagaimana deadlock terjadi, bagaimana Postgres mendeteksinya, dan rancang aturan pengurutan kunci untuk mencegahnya

Deadlock: Deteksi dan Pencegahan adalah pelajaran SQL Academy gratis di CoddyKit. Ini adalah pelajaran 3 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar SQL Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus SQL Academy mencakup 4 pelajaran total.

Apa Itu Kebuntuan?

Dua transaksi masing-masing memegang kunci yang diinginkan oleh transaksi lainnya — tidak ada yang dapat melanjutkan. Basis data mendeteksi siklus tersebut dan membatalkan salah satu transaksi.

Kebuntuan Klasik

Transaksi A mengunci baris 1, transaksi B mengunci baris 2. A meminta baris 2, B meminta baris 1. Keduanya macet.

-- Tx A:
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
-- waiting for B...

-- Tx B:
BEGIN;
UPDATE accounts SET balance = balance - 50 WHERE id = 2;
UPDATE accounts SET balance = balance + 50 WHERE id = 1;
-- waiting for A...

-- ERROR: deadlock detected

PostgreSQL Mendeteksi Kebuntuan

Setiap deadlock_timeout (default 1 detik), PostgreSQL memeriksa siklus kunci. Jika ditemukan, PostgreSQL membatalkan salah satu transaksi dengan kode kesalahan 40P01.

ERROR:  deadlock detected
DETAIL:  Process 1234 waits for ShareLock on transaction 5678 ...

Aturan Urutan Penguncian

Solusinya: selalu dapatkan kunci dalam urutan yang sama di semua jalur kode.

-- Always update the lower id first:
UPDATE accounts SET balance = balance - 100 WHERE id = LEAST(:from, :to);
UPDATE accounts SET balance = balance + 100 WHERE id = GREATEST(:from, :to);

Kebuntuan pada Baris Sibuk

Pembaruan cepat pada baris sibuk yang sama sering memicu penungguan kunci, bukan kebuntuan. Gunakan antrean, bagi baris sibuk menjadi beberapa bagian, atau jalankan pembaruan secara berurutan dalam kode aplikasi.

FOR UPDATE Mengunci Baris yang Dibaca

Dapatkan kunci penulisan saat membaca untuk menghindari kejutan di kemudian hari:

BEGIN;
SELECT * FROM accounts WHERE id IN (1, 2) ORDER BY id FOR UPDATE;
-- both rows locked in id order
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;

Melewati Baris yang Terkunci

Untuk tabel antrean, gunakan pola "ambil baris apa pun yang tersedia":

SELECT * FROM jobs
WHERE status = 'pending'
ORDER BY created_at
LIMIT 1
FOR UPDATE SKIP LOCKED;
-- skips rows other workers have locked

NOWAIT

Gagal seketika alih-alih menunggu:

SELECT * FROM accounts WHERE id = 1 FOR UPDATE NOWAIT;
-- ERROR: could not obtain lock on row in relation "accounts"

Mendiagnosis Kebuntuan

Tingkatkan log_lock_waits dan catat konteks kebuntuan dalam log. Entri log menampilkan kedua transaksi beserta query-nya.

Perulangan Percobaan Ulang Aplikasi

Kebuntuan dapat dipulihkan — coba lagi transaksi yang dibatalkan:

for (let attempt = 0; attempt < 3; attempt++) {
  try {
    await runTransaction();
    break;
  } catch (e) {
    if (e.code === '40P01') continue;     // deadlock
    throw e;
  }
}

Mengurangi Cakupan Penguncian

Persingkat transaksi — setiap baris yang disentuh tetap terkunci sampai COMMIT. Jangan melakukan pemanggilan HTTP atau komputasi lama di dalam transaksi.

Indeks Kunci Asing untuk Menghindari Eskalasi Kunci

Saat Anda menghapus induk, setiap baris anak diperiksa. Tanpa indeks FK, proses tersebut menjadi pemindaian tabel penuh DAN penguncian baris. Buat indeks untuk setiap kolom FK.

Ringkasan

Kebuntuan dapat terjadi — rancang sistem untuk meminimalkannya.

  • Dapatkan kunci dalam urutan yang konsisten
  • Gunakan FOR UPDATE lebih awal untuk menyatakan maksud
  • Gunakan SKIP LOCKED untuk antrean
  • Coba lagi saat terjadi kesalahan kebuntuan (40P01)
  • Jaga agar transaksi tetap singkat

Pemeriksaan Singkat

Apa prinsip desain yang paling andal untuk mencegah kebuntuan?

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Deadlock: Deteksi dan Pencegahan” gratis?

Ya — teks lengkap “Deadlock: Deteksi dan Pencegahan” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus SQL Academy, upgrade ke CoddyKit PRO. Kursus SQL Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Deadlock: Deteksi dan Pencegahan”?

Pahami bagaimana deadlock terjadi, bagaimana Postgres mendeteksinya, dan rancang aturan pengurutan kunci untuk mencegahnya Kamu berlatih SQL Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai SQL Academy?

Tidak diperlukan pengalaman sebelumnya. SQL Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 3 dari 4.

Berapa lama pelajaran “Deadlock: Deteksi dan Pencegahan” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran SQL Academy ini?

Ya. Setiap pelajaran SQL Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Properti ACID dan Anomali
  2. Tingkat Isolasi: READ COMMITTED, REPEATABLE READ, SERIALIZABLE
  3. Deadlock: Deteksi dan Pencegahan
  4. Penguncian Optimistis vs Pesimistis
← Kembali ke SQL Academy