Giao dịch trong một giao dịch


17

Hành vi nào PostgreSQL sẽ hiển thị nếu ví dụ đoạn script bên dưới được gọi

BEGIN;
SELECT * FROM foo;
INSERT INTO foo(name) VALUES ('bar');
BEGIN; <- The point of interest
END;

PostgreSQL sẽ loại bỏ lần thứ hai BEGINhoặc một cam kết sẽ được quyết định ngầm và sau đó chạy BEGIN ENDkhối ở cuối như một giao dịch riêng biệt?

Câu trả lời:


12

Những gì bạn cần là một "giao dịch tự trị" (một tính năng được cung cấp bởi nhà tiên tri). Tại thời điểm này, điều này là không thể trong PostgreSQL. Tuy nhiên, bạn có thể sử dụng SAVEPOINT :

BEGIN;
INSERT ...
SAVEPOINT a;
some error;
ROLLBACK TO SAVEPOINT a;
COMMIT;

Nó không hoàn toàn là một giao dịch tự trị - nhưng, nó cho phép bạn có được "mọi giao dịch" đúng. Bạn có thể sử dụng nó để đạt được điều bạn mong đợi từ các giao dịch tự trị.

Nếu không, không có giải pháp hợp lý khác tại thời điểm này.


13

Bạn có thể tự mình thử:

CẢNH BÁO: đã có một giao dịch đang diễn ra

Nó bắt đầu không có giao dịch (phụ) mới vì các giao dịch lồng nhau không được thực hiện trong PostgreSQL. ( pl/pgsqlVí dụ, bạn có thể thực hiện một số phép thuật trong một chức năng, bắt chước hành vi đó.)

Với PostgreQuery 11, người ta có thể nghĩ các thủ tục lưu trữ thực sự mới và khả năng xử lý các giao dịch của họ sẽ giúp các giao dịch lồng nhau trở nên khả thi. Tuy nhiên, theo tài liệu , đây không phải là trường hợp:

Trong các thủ tục được gọi bởi CALLlệnh cũng như trong các khối mã ẩn danh ( DOlệnh), có thể kết thúc các giao dịch bằng cách sử dụng các lệnh COMMITROLLBACK. Một giao dịch mới được bắt đầu tự động sau khi giao dịch kết thúc bằng các lệnh này, do đó không có lệnh START TRANSACTION riêng.


9

PostgreSQL không hỗ trợ các giao dịch phụ, nhưng SAVEPOINTtính năng này có thể đáp ứng hiệu quả nhu cầu của bạn. Trích dẫn từ tài liệu về lớp truy cập Nâng cao cho PG thông qua lời hứa của Vitaly Tomilov trên GitHub:

PostgreSQL không có hỗ trợ phù hợp cho các giao dịch lồng nhau, nó chỉ hỗ trợ khôi phục một phần thông qua các điểm lưu trữ bên trong các giao dịch. Sự khác biệt giữa hai kỹ thuật là rất lớn, như được giải thích thêm.

Hỗ trợ đúng đắn cho các giao dịch lồng nhau có nghĩa là kết quả của một giao dịch phụ thành công sẽ không được khôi phục khi giao dịch mẹ của nó được khôi phục. Nhưng với các điểm lưu PostgreSQL, nếu bạn quay lại giao dịch cấp cao nhất, kết quả của tất cả các điểm lưu bên trong cũng được khôi phục.

Điểm lưu trữ có thể được sử dụng cho các lần khôi phục một phần đến điểm trước đó trong một giao dịch đang hoạt động. Ví dụ: để thiết lập một điểm lưu trữ và sau đó hoàn tác các hiệu ứng của tất cả các lệnh được thực hiện sau khi nó được thiết lập:

BEGIN;
    INSERT INTO table1 VALUES (1);
    SAVEPOINT my_savepoint;
    INSERT INTO table1 VALUES (2);
    ROLLBACK TO SAVEPOINT my_savepoint;
    INSERT INTO table1 VALUES (3);
COMMIT;

Giao dịch trên sẽ chèn các giá trị 1 và 3, nhưng không phải 2. Xem SAVEPOINTtài liệu để biết thêm thông tin.


0

Đối với Postgresql 9.5 hoặc mới hơn, bạn có thể sử dụng các nhân viên nền động được cung cấp bởi tiện ích mở rộng pg_background. Nó tạo ra giao dịch tự trị. Xin vui lòng, tham khảo trang github của phần mở rộng. Các giải pháp tốt hơn là db_link. Có một hướng dẫn đầy đủ về hỗ trợ giao dịch tự động trong PostgreSQL

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.