MYSQL

Deadlocks in MySQL – Causes, Detection & Prevention

Deadlocks in MySQL

📌 Introduction

In high-concurrency systems, multiple transactions often try to access the same data simultaneously. This can lead to a serious issue called a deadlock.

👉 A deadlock occurs when two or more transactions are waiting for each other to release locks — and none of them can proceed.

Understanding deadlocks is crucial for backend developers, especially when working with MySQL + PHP / APIs / high-traffic systems.


🔒 What is a Deadlock?

A deadlock is a situation where:

  • Transaction A is waiting for Transaction B
  • Transaction B is waiting for Transaction A
  • ❌ Both are stuck forever

👉 MySQL automatically detects deadlocks and kills one transaction to resolve it.


⚙️ How Deadlock Happens (Example)

🧾 Scenario

Two users updating two rows in reverse order.


💻 Example Queries

🔹 Transaction 1

START TRANSACTION;UPDATE accounts SET balance = balance - 100 WHERE id = 1;-- waiting for row 2
UPDATE accounts SET balance = balance + 100 WHERE id = 2;COMMIT;

🔹 Transaction 2

START TRANSACTION;UPDATE accounts SET balance = balance - 50 WHERE id = 2;-- waiting for row 1
UPDATE accounts SET balance = balance + 50 WHERE id = 1;COMMIT;

🚨 What Happens Internally

  • T1 locks row 1
  • T2 locks row 2
  • T1 waits for row 2
  • T2 waits for row 1
    👉 💥 Deadlock occurs

🔍 How to Detect Deadlocks in MySQL

✅ 1. Error Message

MySQL throws:

ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

✅ 2. Show Engine Status

SHOW ENGINE INNODB STATUS;

👉 This gives detailed deadlock logs:

  • Which queries were involved
  • Which transaction was rolled back

✅ 3. Enable Deadlock Logging

SET GLOBAL innodb_print_all_deadlocks = ON;

👉 Logs all deadlocks in MySQL error log


🧑‍💻 PHP Handling Example

try {
$conn->begin_transaction(); $conn->query("UPDATE accounts SET balance = balance - 100 WHERE id = 1");
$conn->query("UPDATE accounts SET balance = balance + 100 WHERE id = 2"); $conn->commit();
} catch (mysqli_sql_exception $e) { if ($e->getCode() == 1213) {
// Deadlock retry logic
echo "Deadlock detected, retrying...";
} $conn->rollback();
}

⚠️ Common Causes of Deadlocks

🔹 1. Different Order of Row Access

👉 Most common cause

🔹 2. Long Transactions

👉 Locks are held for too long

🔹 3. Missing Indexes

👉 Full table scans → more locks

🔹 4. High Concurrency

👉 Too many simultaneous updates

🔹 5. Gap Locks (InnoDB)

👉 Occur in range queries


🛡️ How to Prevent Deadlocks

✅ 1. Access Tables in Same Order

👉 Always follow consistent order


✅ 2. Keep Transactions Short

👉 Commit quickly


✅ 3. Use Proper Indexing

👉 Avoid unnecessary locks


✅ 4. Use Smaller Transactions

👉 Break large operations


✅ 5. Retry Logic (Best Practice)

👉 Always retry failed transactions


✅ 6. Use SELECT … FOR UPDATE Carefully

👉 Lock only required rows


⚖️ Deadlock vs Lock Wait Timeout

FeatureDeadlockLock Wait Timeout
CauseCircular waitingLong wait
DetectionAutomaticTimeout-based
Error Code12131205
SolutionRetryOptimize query

📍 Real-World Use Cases

  • Banking transactions 💰
  • Inventory management 📦
  • Order processing systems 🛒
  • Ticket booking systems 🎟️
No comments yet! You be the first to comment.

Leave a Reply

Your email address will not be published. Required fields are marked *