TopDev

Xử lý Deadlock trong Oracle – Nguyên nhân, cách phát hiện và giải pháp hiệu quả

minhdev 📖 4 phút đọc

Deadlock (bế tắc) là tình trạng phổ biến trong quản trị cơ sở dữ liệu, đặc biệt trong hệ thống đa người dùng. Khi xảy ra deadlock, các tiến trình cùng chờ tài nguyên bị khóa bởi nhau, dẫn đến treo hệ thống hoặc mất hiệu suất. Trong bài viết này, chúng ta sẽ cùng tìm hiểu xử lý deadlock trong Oracle từ nguyên nhân, cách phát hiện cho đến giải pháp phòng ngừa.



1. Deadlock trong Oracle là gì?#

Deadlock trong Oracle xảy ra khi hai hoặc nhiều phiên giao dịch (session) giữ các khóa tài nguyên và đồng thời chờ giải phóng từ nhau. Do mỗi tiến trình chờ tiến trình kia nhả khóa, vòng lặp này không kết thúc, dẫn đến bế tắc.

Ví dụ:

  • Session A khóa dòng X và chờ dòng Y.

  • Session B khóa dòng Y và chờ dòng X. ⇒ Không ai nhả khóa, Oracle phải can thiệp.



2. Oracle xử lý deadlock như thế nào?#

Oracle có cơ chế phát hiện deadlock tự động:

  • Khi phát hiện deadlock, Oracle sẽ chọn một trong các session liên quan để kết thúc (ROLLBACK) và ghi log lỗi vào trace file.

  • Người dùng bị rollback sẽ nhận lỗi:

ORA-00060: deadlock detected while waiting for resource



3. Cách phát hiện Deadlock trong Oracle#

a) Kiểm tra lỗi ORA-00060#

Tra cứu log lỗi:

SELECT * FROM dba_alert_history WHERE message_text LIKE '%deadlock%';

b) Tìm trace file chi tiết#

  • Oracle ghi thông tin deadlock vào trace file trong thư mục user_dump_dest hoặc diag/ (với Oracle 11g trở lên).

  • Dùng lệnh:

SHOW PARAMETER diag;

  • Trace file sẽ mô tả chi tiết:

    Các session liên quan

    • SQL gây deadlock

    • Đối tượng bị khóa

c) Sử dụng view v$sessionv$lock#

SELECT s.sid, s.serial#, s.username, l.type, l.lmode, l.request, l.block FROM v$session s, v$lock l WHERE s.sid = l.sid;



4. Nguyên nhân phổ biến gây Deadlock trong Oracle#

  • Cập nhật nhiều dòng ở nhiều bảng theo thứ tự khác nhau giữa các session.

  • Giao dịch không commit sớm, giữ khóa lâu.

  • Ứng dụng thiết kế chưa tốt, truy vấn lồng nhau không đồng bộ.

  • Không dùng FOR UPDATE NOWAIT dẫn đến chờ vô thời hạn.



5. Cách xử lý và phòng tránh Deadlock#

a) Quy định thứ tự truy cập tài nguyên#

Luôn truy vấn, cập nhật dữ liệu theo thứ tự nhất định ở mọi nơi trong ứng dụng.

b) Giữ giao dịch ngắn gọn#

  • Tránh giữ khóa quá lâu.

  • Luôn COMMIT hoặc ROLLBACK sớm sau khi hoàn tất.

c) Sử dụng FOR UPDATE NOWAIT hoặc FOR UPDATE SKIP LOCKED#

  • Hạn chế chờ khóa quá lâu:

SELECT * FROM employees WHERE department_id = 10 FOR UPDATE NOWAIT;

d) Tối ưu ứng dụng xử lý song song#

  • Hạn chế cập nhật đồng thời vào cùng một dữ liệu.

  • Dùng hàng đợi (queue) hoặc batch để tránh va chạm.

e) Monitor thường xuyên bằng AWR/ASH#

  • AWR Report giúp phát hiện các deadlock thường xuyên xảy ra.

  • Từ đó tối ưu lại ứng dụng hoặc truy vấn.



6. Một ví dụ xử lý deadlock trong Oracle#

Bối cảnh:#

` -- Session 1 UPDATE employees SET salary = salary + 100 WHERE employee_id = 1; -- Session 2 UPDATE employees SET salary = salary + 200 WHERE employee_id = 2;

-- Session 1 tiếp tục: UPDATE employees SET salary = salary + 50 WHERE employee_id = 2; -- Session 2 tiếp tục: UPDATE employees SET salary = salary + 100 WHERE employee_id = 1; `

⇒ Gây deadlock, vì cả hai session đang giữ khóa và chờ lẫn nhau.

Giải pháp:#

  • Thiết lập thứ tự truy cập: luôn cập nhật theo thứ tự employee_id tăng dần.

  • Giảm thời gian giữ khóa.



Kết luận#

Xử lý deadlock trong Oracle đòi hỏi DBA và lập trình viên phải hiểu rõ nguyên nhân gốc rễ và xây dựng thói quen truy cập dữ liệu hợp lý. Oracle có cơ chế tự phát hiện deadlock, nhưng việc thiết kế hệ thống phòng ngừa deadlock ngay từ đầu luôn là cách hiệu quả nhất.

Nếu bạn thường xuyên gặp lỗi ORA-00060, hãy rà soát lại luồng xử lý ứng dụng và tối ưu cách truy cập dữ liệu để đảm bảo hệ thống luôn vận hành trơn tru.

Bài liên quan trong #Database

✓ Đã sao chép link