Những điểm chính cần hiểu:
-
Mọi thứ đang trong một giao dịch. Nếu bạn không tạo một cách rõ ràng với
BEGIN
vàCOMMIT
(hoặcROLLBACK
) một cái được tạo cho bạn chỉ cho câu lệnh đó. -
SELECT
chỉ đọc không nhận được ID giao dịch đầy đủ, họ chỉ nhận được ID giao dịch ảo. Vì vậy, mặc dù đó là một giao dịch,SELECT 1;
hoặc bất cứ điều gì không làm tăng bộ đếm ID giao dịch. -
Đang gọi
txid_current()
lực lượng phân bổ ID giao dịch nếu ID đó chưa được phân bổ. Vì vậy, một giao dịch chỉ đọc bây giờ sẽ có một ID giao dịch, nơi mà trước đây không có.
Tất nhiên, txids cũng được phân bổ qua các phiên. Trong thực tế, ví dụ ở trên của bạn có thể nhận được txid là a + 1 và a + 429 nếu cơ sở dữ liệu đang bận.
Thông thường, không khôn ngoan khi sử dụng ID giao dịch cho bất kỳ thứ gì ở cấp ứng dụng. Cụ thể:
Xử lý xmin
và xmax
dưới dạng các trường cấp hệ thống nội bộ và xử lý kết quả của txid_current()
dưới dạng một giá trị số vô nghĩa.
Chi tiết về cách sử dụng đúng và sai cho xids
Đặc biệt, bạn không bao giờ nên:
- So sánh các xid theo giá trị số để rút ra bất kỳ loại kết luận nào về thứ tự của chúng;
- Thêm hoặc bớt ID giao dịch;
- Sắp xếp các ID giao dịch;
- ID giao dịch tăng hoặc giảm
- So sánh
xid
32 bit trường đã nhập bằngbigint
64 bit xid mở rộng kỷ nguyên, thậm chí để bình đẳng.
Vì vậy, từ góc độ ứng dụng xids không đơn điệu hay thứ tự.
Bạn có thể một cách an toàn:
- so sánh hai xid mở rộng kỷ nguyên 64-bit để biết sự bình đẳng hoặc bất bình đẳng; và
- chuyển xids đến
txid_status(...)
và các chức năng khác được ghi nhận là tham gia xid
Lưu ý:PostgreSQL sử dụng các xids hẹp 32 bit như xid
loại và xid mở rộng kỷ nguyên 64 bit thường được biểu thị dưới dạng bigint
như những thứ được trả về bởi txid_current()
. So sánh những điều này để bình đẳng nhìn chung sẽ có vẻ hoạt động trên một cài đặt cơ sở dữ liệu mới, nhưng khi sự bao bọc của kỷ nguyên đầu tiên đã xảy ra và chúng sẽ không còn bình đẳng nữa. Pg thậm chí không cung cấp cho bạn một cách dễ dàng để xem kỷ nguyên xid ở cấp độ SQL; bạn phải:
select (txid_current() >> 32) AS xid_epoch;
để lấy 32 bit trên của xid mở rộng kỷ nguyên được báo cáo bởi txid_current()
.
Vì vậy, ... bất cứ điều gì bạn đang cố gắng làm, có khả năng là ID giao dịch không phải là cách phù hợp để thực hiện.