CodeGym /Các khóa học /SQL SELF /Giao dịch lồng nhau: SAVEPOINT, ROLLBACK TO SAVEPOINT

Giao dịch lồng nhau: SAVEPOINT, ROLLBACK TO SAVEPOINT

SQL SELF
Mức độ, Bài học
Có sẵn

Trong PostgreSQL KHÔNG có giao dịch lồng nhau thực sự theo nghĩa chuẩn của từ này đâu nha. Chỉ có giao dịch bên ngoài và các "lớp" điểm lưu bên trong nó thôi.

Từ "giao dịch lồng nhau" trong PostgreSQL thường có nghĩa là dùng điểm lưu (savepoints) với mấy lệnh SAVEPOINT, ROLLBACK TO SAVEPOINT, RELEASE SAVEPOINT. Đây không phải là các giao dịch độc lập riêng biệt, mà là các checkpoint đặc biệt bên trong một giao dịch bên ngoài, bạn có thể quay lại đó mà không phải rollback toàn bộ giao dịch.

Ví dụ ngoài đời: bạn đang viết một đoạn văn dài trong editor và thỉnh thoảng bấm ctrl+s để lưu lại. Nếu bạn lỡ làm sai, bạn có thể quay lại một phiên bản đã lưu trước đó mà không mất hết mọi tiến trình.

Lệnh để quản lý điểm lưu

Để quản lý giao dịch lồng nhau, PostgreSQL cho bạn ba lệnh chính:

SAVEPOINT

Lệnh này dùng để tạo "điểm lưu", nơi bạn có thể quay lại khi cần. Điểm này giống như checkpoint trong giao dịch của bạn vậy.

SAVEPOINT mypoint;

ROLLBACK TO SAVEPOINT

Rollback một phần thay đổi được thực hiện sau điểm chỉ định, còn những thay đổi trước đó trong cùng giao dịch bên ngoài thì vẫn giữ nguyên.

ROLLBACK TO SAVEPOINT mypoint;

RELEASE SAVEPOINT

Xóa điểm lưu. Sau đó thì không thể quay lại điểm đó nữa.

RELEASE SAVEPOINT mypoint;

Ví dụ: thêm dữ liệu vào nhiều bảng với khả năng rollback

Giả sử bạn đang làm hệ thống quản lý đơn hàng, cần lưu dữ liệu vào hai bảng: orders và order_items. Nếu lỗi khi thêm vào một bảng thì không nên rollback dữ liệu của bảng còn lại.

BEGIN; -- Bắt đầu giao dịch

-- Tạo điểm lưu
SAVEPOINT before_order;

-- Thêm đơn hàng vào bảng orders
INSERT INTO orders (order_id, customer_id, date)
VALUES (1, 101, CURRENT_DATE);

-- Nếu ở đây có lỗi — rollback lại
SAVEPOINT before_order_items;

-- Thêm sản phẩm vào bảng order_items
INSERT INTO order_items (order_id, product_id, quantity)
VALUES (1, 2001, 4);

-- Nếu có gì đó không ổn
-- ROLLBACK TO SAVEPOINT before_order_items;

-- Xác nhận giao dịch (lưu thay đổi)
COMMIT;

Nếu ở bước thêm bản ghi vào order_items mà có lỗi, bạn có thể quay lại điểm before_order_items, còn thay đổi ở bảng orders vẫn giữ nguyên.

Mẹo thực tế và lỗi thường gặp

Bây giờ bạn đã hiểu cách hoạt động của SAVEPOINT và ROLLBACK TO SAVEPOINT, đây là vài lời khuyên để tránh gặp rắc rối:

  1. Tên điểm lưu. Hãy dùng tên dễ hiểu và duy nhất cho SAVEPOINT. Ví dụ, before_insert, step1 v.v. — sẽ giúp bạn dễ debug hơn.
  2. Đừng quên release SAVEPOINT. Nếu không định quay lại điểm đó nữa thì xóa nó bằng RELEASE SAVEPOINT để giao dịch không bị lộn xộn.
  3. Giao dịch lồng nhau ≠ giao dịch riêng biệt. Nhớ là khi gọi COMMIT thì mọi điểm lưu đều mất hết. Nếu đã COMMIT bên ngoài rồi thì không rollback được nữa đâu.
  4. Khóa dữ liệu. Dù bạn có rollback về điểm lưu thì các lock trên bản ghi được thiết lập trong giao dịch vẫn giữ nguyên. Điều này quan trọng khi làm việc trong môi trường nhiều người dùng.

Giao dịch lồng nhau với SAVEPOINT và ROLLBACK TO SAVEPOINT cho dev một công cụ mạnh để xử lý tình huống phức tạp. Giờ bạn có thể chia nhỏ giao dịch thành các bước linh hoạt, xử lý lỗi gọn gàng và tránh rollback dữ liệu không cần thiết. Nhớ là mỗi lần thấy từ "rollback" thì không phải lúc nào cũng phải hoảng: đôi khi rollback lại là cách tốt nhất để tiến lên phía trước đó.

2
Nhiệm vụ
SQL SELF, mức độ, bài học
Đã khóa
Sử dụng giao dịch lồng nhau để xử lý nhiều thao tác
Sử dụng giao dịch lồng nhau để xử lý nhiều thao tác
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION