Ba tham số cắt ba nguyên nhân treo khác nhau:
statement_timeout— huỷ một câu lệnh chạy quá lâu. Chặn truy vấn nặng ngoài dự kiến chiếm tài nguyên.lock_timeout— huỷ câu lệnh nếu chờ khoá quá lâu, còn thời gian chạy thực tế thì không tính. Quan trọng nhất khi chạy DDL: mộtALTER TABLEchờ khoá sẽ xếp hàng toàn bộ request phía sau.idle_in_transaction_session_timeout— ngắt phiên đãBEGINnhưng ngồi không quá lâu. Đây là loại kết nối gây hại âm thầm nhất: nó vẫn giữ khoá và giữ snapshot cũ khiếnVACUUMkhông dọn được bản ghi chết.
sql
-- đặt cho riêng phiên chạy migration
SET lock_timeout = '3s';
SET statement_timeout = '60s';
ALTER TABLE orders ADD COLUMN note text;Cách đặt thường dùng: đặt statement_timeout và idle_in_transaction_session_timeout ở cấu hình chung cho toàn ứng dụng (vài giây tới vài chục giây), còn lock_timeout đặt riêng ngắn cho phiên migration rồi retry nếu thất bại.
Timeout không thay thế được thiết kế đúng: deadlock chỉ biến mất khi mọi luồng khoá các hàng theo cùng một thứ tự (ví dụ luôn khoá account_id tăng dần). Timeout chỉ đảm bảo hệ thống không đứng im vô hạn khi thiết kế đó bị vi phạm.