Trong PostgreSQL, các hàng sẽ bị khóa khi chúng được cập nhật - trên thực tế, cách điều này thực sự hoạt động là mỗi tuple (phiên bản của một hàng) có một trường hệ thống được gọi là xmin
để cho biết giao dịch nào đã tạo ra tuple đó hiện tại (bằng cách chèn hoặc cập nhật) và trường hệ thống có tên xmax
để cho biết giao dịch nào đã hết hạn tuple đó (bằng cách cập nhật hoặc xóa). Khi bạn truy cập dữ liệu, nó sẽ kiểm tra từng tuple để xác định xem liệu nó có hiển thị với giao dịch của bạn hay không, bằng cách kiểm tra "ảnh chụp nhanh" đang hoạt động của bạn với các giá trị này.
Nếu bạn đang thực hiện CẬP NHẬT và một bộ giá trị phù hợp với điều kiện tìm kiếm của bạn có một xmin sẽ hiển thị trong ảnh chụp nhanh của bạn và xmax của một giao dịch đang hoạt động, nó sẽ chặn, chờ giao dịch đó hoàn tất. Nếu giao dịch lần đầu tiên cập nhật tuple quay trở lại, giao dịch của bạn sẽ đánh thức và xử lý hàng; nếu giao dịch đầu tiên được cam kết, giao dịch của bạn sẽ khởi động và thực hiện hành động tùy thuộc vào mức độ cô lập của giao dịch hiện tại.
Rõ ràng, một bế tắc là kết quả của điều này xảy ra với các hàng theo thứ tự khác nhau. Không có khóa cấp độ hàng trong RAM có thể nhận được cho tất cả các hàng cùng một lúc, nhưng nếu các hàng được cập nhật theo cùng một thứ tự thì bạn không thể có khóa tròn. Rất tiếc, IN(1, 2)
được đề xuất cú pháp không đảm bảo điều đó. Các phiên khác nhau có thể có các yếu tố chi phí khác nhau đang hoạt động, tác vụ "phân tích" nền có thể thay đổi thống kê cho bảng giữa việc tạo ra một kế hoạch và kế hoạch khác hoặc nó có thể đang sử dụng máy quét seqscan và bị ảnh hưởng bởi tối ưu hóa PostgreSQL gây ra một máy quét mới để tham gia một chương trình đã được tiến hành và "lặp lại" để giảm I / O đĩa.
Nếu bạn thực hiện cập nhật lần lượt theo cùng một thứ tự, theo mã ứng dụng hoặc sử dụng con trỏ, thì bạn sẽ chỉ gặp phải các thao tác chặn đơn giản chứ không gặp phải bế tắc. Mặc dù vậy, nói chung, cơ sở dữ liệu quan hệ dễ bị lỗi tuần tự hóa và tốt nhất là truy cập chúng thông qua một khuôn khổ sẽ nhận ra chúng dựa trên SQLSTATE và tự động thử lại toàn bộ giao dịch từ đầu. Trong PostgreSQL, một lỗi tuần tự hóa sẽ luôn có SQLSTATE là 40001 hoặc 40P01.
http://www.postgresql.org/docs/current/interactive/mvcc-intro.html