2015-05-30 18 views
6

Trong PostgreSQL, cơ chế MVCC concurrency control nói rằng: ổ khóaTại sao MVCC yêu cầu khóa cho DML tuyên bố

MVCC mua cho các truy vấn (đọc) dữ liệu không mâu thuẫn với khóa mua cho dữ liệu văn bản, và vì vậy đọc không bao giờ khối văn bản và viết không bao giờ khối đọc

vì vậy, even for READ_COMMITTED, một câu lệnh UPDATE sẽ khóa các hàng hiện đang bị ảnh hưởng nên không có giao dịch nào khác có thể thay đổi chúng, cho đến khi giao dịch vãng lai cam kết hoặc cuộn lại.

Nếu một giao dịch đồng thời phát hành CẬP NHẬT trên các hàng bị khóa, giao dịch thứ hai sẽ chặn cho đến khi giao dịch đầu tiên phát hành khóa.

  1. Đây có phải là hành vi trying to prevent the write-write conflicts không?

  2. Cập nhật bị mất vẫn có thể xảy ra trong READ_COMMITTED, sau khi giao dịch đầu tiên cam kết, lệnh thứ hai sẽ ghi đè hàng (ngay cả khi cơ sở dữ liệu đã thay đổi giữa bắt đầu truy vấn UPDATE và kết thúc truy vấn). Vì vậy, nếu mất cập nhật vẫn còn có thể, tại sao giao dịch thứ hai phải đợi? Không thể các ảnh chụp nhanh cấp hàng được sử dụng để lưu trữ các thay đổi giao dịch không được cam kết để tránh các giao dịch phải chờ các khóa ghi được phát hành?

Trả lời

3

Câu trả lời cho câu hỏi đầu tiên là Có. Không có DBMS nào có thể hỗ trợ ghi chép dơ bẩn; nếu hai giao dịch T1 và T2 đồng thời thực thi và T2 sẽ ghi đè lên một bản cập nhật từ T1, thì hệ thống không thể xử lý trường hợp T1 sau đó phát hành ROLLBACK vì bản cập nhật của T2 đã xảy ra.

Để tránh ghi bẩn, định nghĩa ban đầu để tách biệt ảnh chụp nhanh là "lần commit đầu tiên" - nghĩa là các ghi xung đột sẽ được phép xảy ra, nhưng chỉ giao dịch đầu tiên phát hành COMMIT mới có thể - tất cả các xung đột khác các giao dịch sẽ phải ROLLBACK. Nhưng mô hình lập trình này hơi có vấn đề, nếu không lãng phí, vì một giao dịch có thể cập nhật một tỷ lệ đáng kể của cơ sở dữ liệu chỉ để từ chối khả năng COMMIT ở cuối. Vì vậy, thay vì "người đầu tiên giành chiến thắng" hầu hết các hệ thống DBMS hỗ trợ MVCC thực hiện "chiến thắng cập nhật đầu tiên" bằng cách sử dụng khóa hai pha khá truyền thống.

+0

Nhưng số lần đọc không thể xảy ra, vì chúng tôi đang ở trên READ_COMMITTED. Tôi wad tự hỏi tại sao không cập nhật các bản sao bị cô lập và chỉ tuôn ra chúng tại thời gian cam kết. Ngay bây giờ, trong PostgreSQL, tx thứ 2 chỉ đơn giản là ghi đè lên phiên bản đầu tiên, nhưng cũng có một sự ngăn chặn đang diễn ra. Tại sao không chỉ sử dụng ảnh chụp nhanh theo phạm vi phiên và không chặn ở mức cô lập này. –

+0

Tôi nghĩ ý bạn là "cập nhật các bản sao bị cô lập" sẽ tương ứng với "lần thắng đầu tiên". Và hệ thống có thể thực hiện điều đó - nhưng mô hình lập trình là lẻ, bởi vì mọi giao dịch phải được chuẩn bị để xử lý trường hợp mọi sửa đổi "làm việc" (nghĩa là nó đã hoàn thành và không trả về lỗi) nhưng giao dịch không thể được cam kết . –

+0

Tôi cho rằng mô hình khóa dễ chấp nhận hơn, bởi vì mọi cơ sở dữ liệu đã có một hệ thống phân cấp khóa. Như bạn đã đề cập trước đây, nó không chỉ là dữ liệu hàng mà còn tất cả các chỉ mục. –

Các vấn đề liên quan