Tôi nghĩ rằng bạn đã hiểu sai PREPARE TRANSACTION
.
Tuyên bố đó kết thúc hoạt động trên giao dịch, nghĩa là, nó sẽ được phát hành sau tất cả các công việc đã được thực hiện. Ý tưởng là PREPARE TRANSACTION
thực hiện mọi thứ có thể thất bại trong quá trình cam kết ngoại trừ bản thân cam kết đó. Điều đó để đảm bảo rằng một COMMIT PREPARED
tiếp theo không thể thất bại.
Ý tưởng là quá trình xử lý như sau:
-
Chạy
START TRANSACTION
trên tất cả cơ sở dữ liệu liên quan đến giao dịch phân tán. -
Làm tất cả các công việc. Nếu có lỗi,
ROLLBACK
tất cả các giao dịch. -
Chạy
PREPARE TRANSACTION
trên tất cả các cơ sở dữ liệu. Nếu không thành công ở bất kỳ đâu, hãy chạyROLLBACK PREPARED
trên cơ sở dữ liệu nơi giao dịch đã được chuẩn bị vàROLLBACK
trên những người khác. -
Sau khi
PREPARE TRANSACTION
đã thành công ở mọi nơi, hãy chạyCOMMIT PREPARED
trên tất cả các cơ sở dữ liệu có liên quan.
Bằng cách đó, bạn có thể đảm bảo "tất cả hoặc không có gì" trên một số cơ sở dữ liệu.
Một thành phần quan trọng mà tôi chưa đề cập ở đây là trình quản lý giao dịch phân tán . Nó là một phần mềm liên tục ghi nhớ vị trí hiện đang xử lý thuật toán ở trên để nó có thể dọn dẹp hoặc tiếp tục cam kết sau khi gặp sự cố.
Nếu không có trình quản lý giao dịch phân tán, cam kết hai giai đoạn không có giá trị nhiều và nó thực sự nguy hiểm:nếu các giao dịch bị mắc kẹt trong giai đoạn “chuẩn bị” nhưng chưa được cam kết, chúng sẽ tiếp tục bị khóa và (trong trường hợp PostgreSQL) chặn công việc autovacuum ngay cả khi máy chủ khởi động lại , vì các giao dịch như vậy cần phải liên tục.
Điều này rất khó để làm đúng.