PostgreSQL đi kèm với các tính năng vững chắc, được kiểm tra theo thời gian cho phép bạn xác định chính xác điều gì sẽ xảy ra khi nhiều khách hàng cố gắng cập nhật cùng một dữ liệu đồng thời. Một trong số đó là mức độ cô lập của các giao dịch.
Đọc tiếp để tìm hiểu thêm về cách hoạt động của tính năng phân lập giao dịch trong PostgreSQL.
Giao dịch và Mức độ Cô lập
Giao dịch là cách cơ bản để thay đổi dữ liệu trong RDBMS. RDBMS hiện đại Cho phép nhiều giao dịch chạy đồng thời và do đó có nhiều công cụ khác nhau - một số tiêu chuẩn, một số RDBMS cụ thể - để các nhà phát triển ứng dụng chỉ định cách giao dịch của họ nên hoặc không nên tương tác với các giao dịch khác.
Mức cô lập giao dịch và khóa bi quan là hai công cụ như vậy. Mặc dù chúng cần thiết cho tính toàn vẹn và hiệu suất của dữ liệu, nhưng rất tiếc, chúng không được chăm chút để hiểu hoặc sử dụng.
Mức cô lập của một giao dịch, trong PostgreSQL, có thể là một trong số:
- Đã cam kết đọc
- Đọc lặp lại
- Có thể nối tiếp hóa
Mỗi giao dịch đều có mức cô lập của nó được đặt thành một trong những mức này khi nó được tạo. Mức mặc định là “đọc cam kết”.
Lưu ý rằng tiêu chuẩn SQL cũng định nghĩa "đọc không cam kết", không được hỗ trợ trong Postgres. Bạn phải sử dụng mức “đã đọc cam kết” gần nhất, cao hơn.
Hãy xem những cấp độ này có ý nghĩa gì.
Đã cam kết đọc
Điều gì xảy ra khi một giao dịch (chưa hoàn thành) chèn các hàng trong bảng và giao dịch khác (cũng chưa hoàn thành) cố gắng đọc tất cả các hàng trong bảng? Nếu giao dịch thứ hai có thể nhìn thấy các hàng được chèn bởi giao dịch đầu tiên, thì lần đọc đó được gọi là đọc bẩn - bởi vì giao dịch đầu tiên có thể quay ngược trở lại và giao dịch thứ hai sẽ đọc các hàng "ảo" chưa từng tồn tại.
Bản cam kết đã đọc mức độ cô lập đảm bảo rằng các lần đọc bẩn sẽ không bao giờ xảy ra. Đây là một ví dụ:
Như bạn có thể thấy, giao dịch thứ hai không thể đọc dữ liệu chưa được cam kết của giao dịch đầu tiên. Trong PostgreSQL, không thể hạ mức cách ly xuống dưới mức này để cho phép đọc bẩn.
Đọc lặp lại
Tuy nhiên, một vấn đề khác là số lần đọc không lặp lại. Những điều này xảy ra khi atransaction đọc một hàng và sau đó đọc lại nó một chút sau đó nhưng nhận được kết quả khác - bởi vì hàng đã được cập nhật ở giữa bởi một giao dịch khác. Đã đọc không thể lặp lại , như được hiển thị trong ví dụ này:
Để khắc phục sự cố này, hãy đặt mức cô lập của giao dịch thành “có thể đọc lại”. Sau đó, PostgreSQL sẽ đảm bảo rằng lần đọc thứ hai (hoặc bất kỳ) cũng sẽ trả về kết quả tương tự như lần đọc đầu tiên. Đây là tình huống tương tự ở mức cô lập được nâng cấp:
Lưu ý rằng mức độ cách ly đã được chỉ định cùng với BEGINstatement. Cũng có thể chỉ định điều này ở cấp độ kết nối (như một tham số kết nối), như một tham số cấu hình (default_transaction_isolation
) và sử dụng câu lệnh SET TRANSACTION.
Serializable
Mức độ cách ly tiếp theo giải quyết sự cố mất bản cập nhật . Các cập nhật được thực hiện trong một giao dịch có thể bị “mất” hoặc bị ghi đè bởi một giao dịch khác xảy ra chạy đồng thời, như được hiển thị ở đây:
Đây là khối CẬP NHẬT của giao dịch thứ hai, vì PostgreSQL đặt khóa để ngăn cập nhật khác cho đến khi giao dịch đầu tiên kết thúc. Tuy nhiên, thay đổi của giao dịch đầu tiên bị mất vì giao dịch thứ hai “ghi đè” lên chuỗi.
Nếu loại hành vi này không được chấp nhận, bạn có thể nâng cấp mức cách ly lên thành có thể nối tiếp hóa:
Ở cấp độ này, cam kết của giao dịch thứ hai không thành công. Các hành động của bên giao dịch thứ hai dựa trên các dữ kiện đã được đưa ra là không hợp lệ vào thời điểm nó sắp cam kết.
Trong khi tuần tự hóa cung cấp mức độ an toàn cao nhất, điều đó cũng có nghĩa là ứng dụng phải phát hiện các lỗi cam kết như vậy và thử lại giao dịch entiretransaction.