Database Deadlock, Penyebab dan Cara Mengatasinya

Web & Development •

Database perlu menangani banyak transaksi yang berjalan secara bersamaan. Misalnya, beberapa pengguna dapat melakukan pembelian, memperbarui stok, atau mengubah data dalam waktu yang hampir sama. Agar data tetap konsisten, database menggunakan mekanisme seperti transaksi dan locking. Namun, penggunaan lock secara bersamaan juga dapat menimbulkan masalah. Dua transaksi bisa saling menunggu karena masing-masing memegang lock yang dibutuhkan transaksi lainnya. Kondisi ini disebut database deadlock.

Deadlock dapat menghentikan proses transaksi sampai database mengambil tindakan untuk memutus kondisi tersebut. Karena itu, memahami cara kerja database deadlock penting bagi developer maupun administrator database, terutama pada aplikasi dengan banyak transaksi secara bersamaan.

Apa Itu Database Deadlock?

Database deadlock adalah kondisi ketika dua atau lebih transaksi saling menunggu resource yang sedang dikunci oleh transaksi lainnya sehingga tidak ada transaksi yang dapat melanjutkan prosesnya. Kondisi ini biasanya muncul ketika beberapa transaksi mengakses resource yang sama dalam waktu bersamaan. Resource tersebut dapat berupa baris data, halaman, tabel, atau objek database lain yang menggunakan mekanisme locking.

Sebagai contoh, terdapat dua transaksi, yaitu Transaksi A dan Transaksi B. Transaksi A lebih dulu mengunci data pada tabel orders, sedangkan Transaksi B mengunci data pada tabel payments. Setelah itu, Transaksi A membutuhkan data yang sedang dikunci Transaksi B. Pada saat yang sama, Transaksi B membutuhkan data yang sedang dikunci Transaksi A.

Akibatnya, Transaksi A menunggu Transaksi B, sementara Transaksi B juga menunggu Transaksi A. Tidak ada transaksi yang dapat melanjutkan prosesnya tanpa melepaskan lock yang dimiliki.

Deadlock berbeda dengan blocking biasa. Pada blocking, satu transaksi dapat menunggu transaksi lain selesai dan melepaskan lock. Setelah transaksi pertama selesai, transaksi yang menunggu dapat melanjutkan prosesnya. Pada deadlock, transaksi yang saling menunggu tidak dapat menyelesaikan proses tanpa adanya intervensi dari database atau aplikasi.

Baca juga: Kesalahan Umum Menggunakan Transaction Control Language – IDCloudHost

Penyebab Database Deadlock

database deadlock

Deadlock tidak muncul secara acak. Biasanya terdapat pola tertentu dalam transaksi atau cara aplikasi mengakses database.

1. Transaksi Mengakses Resource dalam Urutan Berbeda

Urutan akses menjadi salah satu penyebab umum deadlock. Misalnya, Transaksi A mengakses tabel users kemudian orders, sedangkan Transaksi B mengakses orders kemudian users.

Jika keduanya berjalan bersamaan dan menggunakan lock yang saling bertentangan, deadlock dapat terjadi. Karena itu, aplikasi yang menggunakan beberapa tabel dalam satu transaksi perlu mempertimbangkan urutan akses resource.

2. Transaksi Berjalan Terlalu Lama

Semakin lama sebuah transaksi mempertahankan lock, semakin lama transaksi lain harus menunggu resource tersebut. Transaksi yang berjalan terlalu lama dapat muncul karena query berat, terlalu banyak operasi dalam satu transaksi, atau aplikasi menempatkan proses yang sebenarnya tidak perlu berada di dalam transaksi.

3. Banyak Transaksi Berjalan Bersamaan

Aplikasi dengan banyak pengguna dapat menjalankan banyak transaksi secara bersamaan. Semakin tinggi tingkat concurrency, semakin banyak transaksi yang dapat saling mengakses resource yang sama.

Kondisi ini tidak otomatis menyebabkan deadlock. Namun, semakin banyak transaksi yang berjalan bersamaan, semakin kompleks interaksi antar-lock yang perlu dikelola database.

4. Penggunaan Lock yang Tidak Tepat

Cara aplikasi menggunakan locking juga dapat mempengaruhi risiko deadlock. Transaksi yang mengambil terlalu banyak lock atau mempertahankan lock lebih lama dari kebutuhan dapat meningkatkan kemungkinan transaksi lain ikut menunggu. Karena itu, developer perlu memahami kebutuhan locking sesuai jenis transaksi yang dibuat.

5. Transaksi Mengakses Banyak Resource

Transaksi yang hanya mengakses satu resource memiliki pola yang lebih sederhana dibandingkan transaksi yang mengunci banyak resource. Ketika sebuah transaksi perlu mengubah beberapa tabel atau baris, jumlah hubungan antar-lock juga meningkat. Jika transaksi lain menggunakan resource yang sama dengan urutan berbeda, peluang terbentuknya deadlock menjadi lebih besar.

Dampak Database Deadlock

Deadlock tidak hanya berkaitan dengan error pada database. Jika sering terjadi, kondisi ini dapat memengaruhi aplikasi secara lebih luas.

1. Salah Satu Transaksi Harus Dibatalkan

Database biasanya perlu memilih salah satu transaksi yang terlibat sebagai deadlock victim. Transaksi tersebut akan dihentikan atau di-rollback agar lock yang dimilikinya dapat dilepaskan.

Setelah itu, transaksi lain yang sebelumnya menunggu dapat melanjutkan proses. Pada SQL Server, misalnya, Database Engine mendeteksi deadlock dan memilih salah satu transaksi untuk dihentikan agar transaksi lainnya dapat berjalan.

2. Aplikasi Dapat Menerima Error

Ketika database membatalkan transaksi, aplikasi dapat menerima error. Jika aplikasi tidak memiliki mekanisme penanganan yang tepat, pengguna dapat melihat kegagalan transaksi. Contohnya, pengguna dapat menerima pesan bahwa proses pembayaran gagal meskipun penyebab sebenarnya berasal dari konflik transaksi di database.

3. Transaksi Perlu Dijalankan Kembali

Pada kondisi tertentu, aplikasi dapat mencoba menjalankan kembali transaksi yang gagal karena deadlock. MySQL merekomendasikan agar aplikasi selalu siap menjalankan ulang transaksi ketika transaksi mengalami rollback akibat deadlock.

Namun, mekanisme retry harus dirancang dengan hati-hati. Aplikasi tidak sebaiknya terus mengulang transaksi tanpa batas karena kondisi tersebut justru dapat menambah beban database.

4. Performa Aplikasi Dapat Terganggu

Deadlock yang sering terjadi dapat meningkatkan jumlah transaksi yang harus diulang. Kondisi tersebut dapat menambah pekerjaan database dan aplikasi. Pada sistem dengan traffic tinggi, efeknya dapat terasa pada waktu respons dan throughput transaksi.

Baca juga: Database Connection Pooling, Cara Kerja & Manfaat untuk Aplikasi – IDCloudHost

Bagaimana Database Mendeteksi Deadlock?

Database modern biasanya memiliki mekanisme untuk mendeteksi kondisi deadlock. Database tidak hanya membiarkan transaksi saling menunggu tanpa batas.

1. Database Memantau Lock

Database mencatat hubungan antara transaksi dan resource yang sedang digunakan. Informasi tersebut membantu database mengetahui transaksi mana yang sedang menunggu resource tertentu. Ketika sebuah transaksi meminta resource yang sedang terkunci, database dapat mencatat hubungan tunggunya.

2. Database Mencari Siklus

Deadlock memiliki karakteristik berupa siklus ketergantungan. Misalnya, Transaksi A menunggu Transaksi B, Transaksi B menunggu Transaksi C, sedangkan Transaksi C menunggu Transaksi A.

Jika database menemukan pola seperti ini, database dapat mengenalinya sebagai deadlock. SQL Server memiliki mekanisme khusus untuk mendeteksi deadlock dan menentukan tindakan yang perlu dilakukan.

3. Database Memilih Transaksi untuk Dibatalkan

Setelah menemukan deadlock, database perlu memutus siklus tersebut. Salah satu cara adalah membatalkan salah satu transaksi. Transaksi yang dibatalkan akan melepaskan lock yang dimilikinya. Dengan begitu, transaksi lain dapat memperoleh resource dan melanjutkan proses.

Pemilihan transaksi yang dibatalkan dapat bergantung pada aturan database. SQL Server, misalnya, mempertimbangkan deadlock priority dan biaya rollback ketika menentukan deadlock victim.

Cara Mengatasi Database Deadlock

Deadlock dapat terjadi pada sistem database yang memiliki transaksi bersamaan. Karena itu, aplikasi perlu memiliki strategi untuk menangani kondisi tersebut.

1. Gunakan Retry Mechanism

Salah satu cara yang umum adalah menjalankan kembali transaksi ketika database membatalkannya karena deadlock. Misalnya, aplikasi menjalankan transaksi pembelian. Jika transaksi mengalami deadlock dan database melakukan rollback, aplikasi dapat mencoba transaksi tersebut kembali setelah jeda singkat.

Namun, jumlah percobaan perlu dibatasi. Aplikasi juga dapat menggunakan jeda dengan durasi yang bervariasi agar transaksi yang mengalami konflik tidak langsung mencoba pada waktu yang sama.

2. Samakan Urutan Akses Resource

Jika beberapa transaksi membutuhkan resource yang sama, usahakan transaksi mengakses resource tersebut dengan urutan yang konsisten. Misalnya, seluruh transaksi yang perlu mengubah products dan orders selalu mengakses products terlebih dahulu, kemudian orders.

Pendekatan ini dapat mengurangi kemungkinan dua transaksi mengambil lock dalam urutan berlawanan. Microsoft juga merekomendasikan akses objek dalam urutan yang sama sebagai salah satu cara untuk meminimalkan deadlock.

3. Buat Transaksi Lebih Singkat

Batasi isi transaksi hanya pada operasi yang memang membutuhkan atomicity. Hindari menempatkan proses yang memerlukan waktu lama di dalam transaksi jika proses tersebut tidak membutuhkan lock database. Semakin singkat transaksi berlangsung, semakin cepat transaksi dapat melakukan commit atau rollback dan melepaskan resource yang digunakan.

4. Hindari Interaksi Pengguna dalam Transaksi

Transaksi sebaiknya tidak menunggu pengguna melakukan tindakan tertentu. Sebagai contoh, aplikasi sebaiknya tidak membuka transaksi lalu menunggu pengguna mengisi formulir atau memberikan konfirmasi.

Selama transaksi masih aktif, database dapat mempertahankan lock tertentu.Selesaikan interaksi pengguna terlebih dahulu, kemudian jalankan transaksi ketika seluruh informasi sudah tersedia.

5. Gunakan Isolation Level Sesuai Kebutuhan

Isolation level menentukan bagaimana transaksi berinteraksi ketika beberapa transaksi berjalan secara bersamaan. Isolation level yang lebih ketat dapat memberikan tingkat isolasi lebih tinggi, tetapi juga dapat memengaruhi concurrency dan locking.

Karena itu, pilih isolation level berdasarkan kebutuhan aplikasi, bukan sekadar menggunakan tingkat isolasi paling tinggi. Pengaturan yang tepat perlu mempertimbangkan keseimbangan antara konsistensi data dan kebutuhan concurrency.

6. Tangani Error pada Sisi Aplikasi

Aplikasi perlu mengenali error yang menunjukkan bahwa transaksi gagal akibat deadlock. Setelah itu, aplikasi dapat melakukan rollback atau retry sesuai mekanisme database dan framework yang digunakan. Error handling yang baik membuat pengguna tidak harus menghadapi pesan error database yang sulit dipahami.

Untuk transaksi penting seperti pembayaran atau pemesanan, mekanisme retry juga perlu mempertimbangkan idempotency. Aplikasi harus memastikan pengulangan transaksi tidak menyebabkan operasi yang sama tercatat lebih dari sekali.

Cara Mencegah Database Deadlock

Deadlock tidak selalu dapat dihilangkan sepenuhnya, terutama pada aplikasi yang menangani banyak transaksi secara bersamaan. Namun, developer dapat mengurangi kemungkinannya dengan beberapa pendekatan.

1. Rancang Transaksi dengan Jelas

Tentukan operasi mana yang memang membutuhkan satu transaksi. Jangan memasukkan terlalu banyak proses yang tidak berkaitan ke dalam transaksi yang sama. Transaksi yang memiliki cakupan jelas akan lebih mudah dipahami dan dikelola.

2. Konsisten dalam Urutan Query

Gunakan urutan akses resource yang konsisten di berbagai bagian aplikasi. Jika satu transaksi selalu mengakses users kemudian orders, transaksi lain yang membutuhkan kedua tabel tersebut sebaiknya menggunakan urutan yang sama.

3. Perhatikan Query yang Berjalan dalam Transaksi

Query yang membutuhkan waktu lama dapat membuat transaksi mempertahankan lock lebih lama. Karena itu, perhatikan query yang digunakan di dalam transaksi. Index yang sesuai juga dapat membantu database menemukan data dengan lebih efisien. Namun, penggunaan index tetap perlu disesuaikan dengan pola query dan struktur tabel.

4. Monitor Deadlock Secara Berkala

Jika aplikasi sering mengalami deadlock, jangan hanya mengandalkan retry. Cari tahu transaksi mana yang saling berkonflik. Database seperti SQL Server menyediakan berbagai tools dan informasi untuk menganalisis deadlock.

MySQL InnoDB juga menyediakan mekanisme untuk mendeteksi dan menangani deadlock. Dengan melihat pola deadlock, developer dapat menemukan bagian aplikasi yang perlu diperbaiki.

Baca juga: Jenis-Jenis Database Index dan Kapan Harus Menggunakannya – IDCloudHost

Penutup

Database biasanya mendeteksi deadlock dan membatalkan salah satu transaksi untuk memutus siklus. Dari sisi aplikasi, Anda dapat menangani kondisi tersebut dengan retry mechanism, transaksi yang lebih singkat, urutan akses resource yang konsisten, serta error handling yang tepat.

Deadlock memang tidak selalu dapat dihindari, tetapi desain transaksi dan pengelolaan database yang baik dapat mengurangi frekuensinya. Untuk aplikasi dengan banyak transaksi, pastikan database berjalan pada server dengan resource yang sesuai agar workload dapat berjalan lebih stabil. IDCloudHost Cloud VPS menyediakan resource yang fleksibel untuk mendukung aplikasi dan database sesuai kebutuhan workload Anda.