Error Encyclopedia

Database Deadlock Detected Error

Fix 'deadlock detected' errors in PostgreSQL and other databases. Learn why concurrent transactions deadlock and how to prevent them.

What Does This Error Mean?

A deadlock occurs when two or more transactions are waiting for each other to release locks, creating a circular dependency. The database automatically detects deadlocks and terminates one of the transactions to break the cycle.

Common Causes

1

Two transactions updating the same rows in different orders

2

Transaction A locks row 1 and waits for row 2 while Transaction B locks row 2 and waits for row 1

3

Long-running transactions holding locks while other transactions wait

4

Missing indexes causing table-level locks instead of row-level locks

5

Application-level lock ordering inconsistency

How to Fix It

Always lock resources in the same order

Ensure all transactions access tables and rows in the same consistent order.

// ❌ Deadlock prone
// Transaction 1: update A → update B
// Transaction 2: update B → update A

// ✅ Safe: always update in the same order
always update A first, then B

// In application code, sort IDs before updating
transaction(async (tx) => {
  const ids = [userId, otherId].sort() // Sort to ensure consistent order
  for (const id of ids) {
    await tx.users.update({ where: { id }, data: { ... } })
  }
})

Implement retry logic

Catch deadlock errors and retry the transaction.

import { Prisma } from "@prisma/client"

async function retryOnDeadlock(fn, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await fn()
    } catch (err) {
      if (err instanceof Prisma.PrismaClientKnownRequestError && err.code === "P2034") {
        console.log(`Deadlock detected, retrying (${i + 1}/${maxRetries})`)
        continue
      }
      throw err
    }
  }
}

Keep transactions short

Minimize the duration of transactions to reduce lock contention.

// ❌ Long transaction with external API call inside
await prisma.$transaction(async (tx) => {
  await tx.users.update(...)
  await fetch("https://slow-api.com/data") // 🔴 Holds lock while waiting!
  await tx.orders.update(...)
})

// ✅ Do external work outside the transaction
const data = await fetch("https://slow-api.com/data").then(r => r.json())
await prisma.$transaction(async (tx) => {
  await tx.users.update(...)
  await tx.orders.update({ ...data })
})

Related Tools

Use these tools to debug and fix this error:

Related Errors

Other common errors in this category: