PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Khóa và giao dịch trong các bưu điện sẽ chặn một truy vấn

Hành vi bạn mô tả là bình thường và được mong đợi trong bất kỳ cơ sở dữ liệu quan hệ giao dịch nào.

Nếu PostgreSQL hiển thị cho bạn giá trị edited cho SELECT đầu tiên sẽ là sai khi làm như vậy - đó được gọi là "đọc bẩn" và là tin xấu trong cơ sở dữ liệu.

PostgreSQL sẽ được phép đợi tại SELECT cho đến khi bạn cam kết hoặc quay trở lại, nhưng nó không bắt buộc theo tiêu chuẩn SQL, bạn đã không nói với nó rằng bạn muốn đợi và nó không phải đợi vì bất kỳ lý do kỹ thuật nào, vì vậy nó sẽ trả về dữ liệu bạn đã yêu cầu cho ngay lập tức. Rốt cuộc, cho đến khi nó được cam kết, update đó chỉ loại tồn tại - nó vẫn có thể xảy ra hoặc có thể không xảy ra.

Nếu PostgreSQL luôn đợi ở đây, thì bạn sẽ nhanh chóng gặp phải tình huống chỉ có một kết nối có thể làm bất cứ điều gì với cơ sở dữ liệu tại một thời điểm. Không đẹp cho hiệu suất và hoàn toàn không cần thiết trong phần lớn thời gian.

Nếu bạn muốn đợi UPDATE đồng thời (hoặc DELETE ), bạn sẽ sử dụng SELECT ... FOR SHARE . (Nhưng lưu ý rằng điều này sẽ không hoạt động đối với INSERT ).

Chi tiết:

SELECT không có FOR UPDATE hoặc FOR SHARE mệnh đề không có bất kỳ khóa cấp độ hàng nào. Vì vậy, nó nhìn thấy bất cứ điều gì là hàng được cam kết hiện tại và không bị ảnh hưởng bởi bất kỳ giao dịch trong chuyến bay nào có thể đang sửa đổi hàng đó. Các khái niệm được giải thích trong phần MVCC của tài liệu . Ý tưởng chung là PostgreSQL là copy-on-write, với cách lập phiên bản cho phép nó trả lại bản sao chính xác dựa trên những gì giao dịch hoặc câu lệnh có thể "nhìn thấy" tại thời điểm nó bắt đầu - cái mà PostgreSQL gọi là "snapshot".

Trong READ COMMITTED mặc định ảnh chụp nhanh cách ly được thực hiện ở cấp câu lệnh, vì vậy nếu bạn SELECT một hàng, COMMIT một thay đổi đối với nó từ một giao dịch khác và SELECT nó một lần nữa, bạn sẽ thấy các giá trị khác nhau ngay cả trong một lần chuyển đổi. Bạn có thể sử dụng SNAPSHOT cô lập nếu bạn không muốn thấy các thay đổi được cam kết sau khi giao dịch bắt đầu hoặc SERIALIZABLE cô lập để tăng cường bảo vệ chống lại một số loại phụ thuộc giữa các giao dịch.

Xem chương cách ly giao dịch trong tài liệu .

Nếu bạn muốn một SELECT để đợi các giao dịch đang tiến hành cam kết hoặc khôi phục các thay đổi đối với các hàng đang được chọn, bạn phải sử dụng SELECT ... FOR SHARE . Điều này sẽ chặn trên ổ khóa được thực hiện bởi một UPDATE hoặc DELETE cho đến khi giao dịch đã khóa trở lại hoặc cam kết.

INSERT thì khác, tuy nhiên - các bộ giá trị không tồn tại đối với các giao dịch khác cho đến khi cam kết. Cách duy nhất để đợi INSERT đồng thời s là lấy một EXCLUSIVE khóa cấp bảng, vì vậy bạn biết không ai khác đang thay đổi bảng trong khi bạn đọc nó. Thông thường, việc cần làm đó có nghĩa là bạn gặp sự cố thiết kế trong ứng dụng - ứng dụng của bạn không nên quan tâm nếu có insert chưa cam kết vẫn đang bay.

Xem chương khóa rõ ràng của tài liệu .



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tham gia bên trong với SqlAlchemy

  2. Ánh xạ Chế độ xem SQL tới Thực thể jpa ngủ đông

  3. Postgres:Chuyển đổi varchar thành văn bản

  4. Làm thế nào để chuyển đổi postgres json thành số nguyên

  5. Bộ lập lịch sự kiện trong PostgreSQL?