© 2026 Laravel

Database Deadlock: Khi hệ thống tự 'khóa' nhau

2 phút đọc
#database #sql #deadlock #performance #laravel

Mục lục bài viết

Sử dụng các mục để điều hướng nhanh

#1. Bài toán

Hai giao dịch A và B cùng cập nhật 2 dòng dữ liệu (ví dụ: chuyển tiền từ tài khoản X sang Y và ngược lại). Giao dịch A khóa X chờ Y, giao dịch B khóa Y chờ X. Hệ thống treo!

#2. Nguyên lý

Deadlock xảy ra do sự tranh chấp khóa (Locking) theo chu kỳ.

  • Tại sao hay gặp ở Laravel: Dùng DB::transaction() với quá nhiều logic bên trong, hoặc cập nhật quá nhiều bảng cùng lúc.

#3. Kinh nghiệm thực chiến

  • Thứ tự (Ordering): Luôn cập nhật theo một thứ tự cố định (ví dụ: luôn cập nhật ID nhỏ trước ID lớn).
  • Transaction nhỏ: Đừng bao giờ gọi API hoặc xử lý logic tốn thời gian (gửi mail, resize ảnh) trong DB::transaction. Chỉ giữ SQL thuần ở đó.
  • Locking: Dùng lockForUpdate() một cách thận trọng.

#4. Mẹo phỏng vấn

Q: Làm sao để debug deadlock khi hệ thống đang chạy? A: Dùng lệnh SHOW ENGINE INNODB STATUS;. Nó sẽ hiển thị “LATEST DETECTED DEADLOCK” giúp bạn biết chính xác hai câu SQL nào đang “đá” nhau. Mẹo đánh đố: Luôn thử lại (Retry) transaction trong Laravel bằng DB::transaction(callback, 3). Số 3 nghĩa là Laravel sẽ tự retry 3 lần nếu gặp deadlock.

Bài viết liên quan