Giao dịch (Transaction) trong PostgreSQL là một nhóm các câu lệnh SQL được thực hiện như một đơn vị logic duy nhất. Mục tiêu của giao dịch là đảm bảo rằng tất cả các thao tác trong đó đều được hoàn thành hoặc không thao tác nào được thực hiện nếu có lỗi xảy ra, từ đó duy trì tính nhất quán của cơ sở dữ liệu.
Đặc điểm chính của giao dịch
Giao dịch tuân theo các tính chất ACID, giúp đảm bảo tính tin cậy và bảo mật trong cơ sở dữ liệu.
- Atomicity (Tính nguyên tử): Một giao dịch phải được thực hiện toàn bộ hoặc không thực hiện gì cả. Nếu bất kỳ thao tác nào trong giao dịch bị lỗi, tất cả các thay đổi sẽ bị hủy bỏ.
- Consistency (Tính nhất quán): Sau khi giao dịch hoàn thành, cơ sở dữ liệu sẽ ở trạng thái nhất quán. Điều này có nghĩa là nếu dữ liệu đã hợp lệ trước khi giao dịch bắt đầu, nó sẽ vẫn hợp lệ sau khi giao dịch kết thúc.
- Isolation (Tính cô lập): Giao dịch của bạn sẽ hoạt động độc lập với các giao dịch khác. Tùy thuộc vào mức độ cô lập, các thay đổi của một giao dịch sẽ không thể nhìn thấy đối với giao dịch khác cho đến khi giao dịch hoàn tất.
- Durability (Tính bền vững): Sau khi giao dịch hoàn tất và các thay đổi được cam kết (committed), dữ liệu sẽ được lưu trữ bền vững trong cơ sở dữ liệu, ngay cả khi hệ thống gặp sự cố.
Các lệnh liên quan đến giao dịch trong PostgreSQL
BEGIN: Bắt đầu một giao dịch.
COMMIT: Kết thúc giao dịch và lưu tất cả các thay đổi vào cơ sở dữ liệu.
ROLLBACK: Hủy bỏ toàn bộ giao dịch và hoàn nguyên cơ sở dữ liệu về trạng thái trước khi giao dịch bắt đầu.
SAVEPOINT: Tạo điểm lưu tạm thời trong một giao dịch. Nếu có sự cố, bạn có thể quay lại điểm lưu này mà không cần hủy bỏ toàn bộ giao dịch.
SAVEPOINT savepoint_name;
RELEASE SAVEPOINT: Hủy bỏ một điểm lưu (savepoint) đã tạo.
RELEASE SAVEPOINT savepoint_name;
ROLLBACK TO SAVEPOINT: Quay lại điểm lưu tạm thời và hủy bỏ tất cả các thay đổi từ điểm đó đến hiện tại.
ROLLBACK TO SAVEPOINT savepoint_name;
Ví dụ về giao dịch trong PostgreSQL
Giả sử bạn muốn thực hiện hai thao tác: cập nhật số dư của hai tài khoản trong một giao dịch chuyển tiền. Giao dịch này cần đảm bảo rằng nếu một thao tác cập nhật bị lỗi, toàn bộ quá trình sẽ được hoàn nguyên.
BEGIN;
-- Trừ tiền từ tài khoản A
UPDATE accounts
SET balance = balance - 100
WHERE account_id = 'A';
-- Cộng tiền vào tài khoản B
UPDATE accounts
SET balance = balance + 100
WHERE account_id = 'B';
-- Xác nhận giao dịch
COMMIT;
Nếu một trong hai câu lệnh UPDATE
gặp lỗi (ví dụ do tài khoản A không đủ số dư), bạn có thể sử dụng ROLLBACK
để hủy bỏ toàn bộ giao dịch, đảm bảo rằng không có thay đổi nào được lưu lại.
Tính năng bổ sung: Tự động giao dịch (Autocommit)
Trong PostgreSQL, chế độ mặc định là autocommit. Điều này có nghĩa là mỗi câu lệnh SQL đơn lẻ như INSERT
, UPDATE
, hoặc DELETE
được coi là một giao dịch tự động, và PostgreSQL sẽ tự động thực hiện COMMIT
sau khi câu lệnh hoàn thành. Tuy nhiên, khi sử dụng các lệnh như BEGIN
, COMMIT
, hoặc ROLLBACK
, bạn có thể kiểm soát thủ công các giao dịch.
Các mức độ cô lập (Transaction Isolation Levels)
PostgreSQL hỗ trợ nhiều mức độ cô lập khác nhau cho các giao dịch:
- Read Uncommitted: Thấy các thay đổi chưa được
COMMIT
của các giao dịch khác (không được hỗ trợ hoàn toàn trong PostgreSQL).
- Read Committed (mặc định): Chỉ thấy các thay đổi đã
COMMIT
của các giao dịch khác.
- Repeatable Read: Mọi dữ liệu mà giao dịch đọc được sẽ không thay đổi trong suốt giao dịch đó, ngay cả khi các giao dịch khác
COMMIT
.
- Serializable: Cấp độ cô lập cao nhất, đảm bảo không có sự can thiệp nào giữa các giao dịch.
Bạn có thể thay đổi mức độ cô lập cho giao dịch bằng lệnh:
SET TRANSACTION ISOLATION LEVEL serializable;
BEGIN;
-- các thao tác SQL khác
COMMIT;
Tóm lại, giao dịch trong PostgreSQL là một công cụ mạnh mẽ giúp đảm bảo tính nhất quán, bảo mật và bền vững của dữ liệu khi thực hiện các thao tác trên cơ sở dữ liệu.