Transaction Isolation Levels trong DBMS

Trong DBMS, duy trì tính nhất quán và tính toàn vẹn của dữ liệu là rất quan trọng. Một trong những nguyên tắc cơ bản đảm bảo tính toàn vẹn này là khái niệm về các thuộc tính ACID, bao gồm Tính nguyên tử (Atomicity), Tính nhất quán (Consistency), Mức độ cô lập(Isolation), và Tính bền vững (Durability). Trong số này, Isolation đóng vai trò quan trọng trong việc xác định cách mà tính nguyên tắc của transaction được nhìn thấy bởi người dùng và hệ thống khác tương tác với cơ sở dữ liệu. Các mức độ cô lập trong transaction (Transaction Isolation Levels) là nền tảng để xác định mức độ isolation mà một transaction phải duy trì so với các transaction đồng thời, từ đó bảo vệ tính toàn vẹn của dữ liệu.

I. Hiểu về các hiện tượng cô lập

  • Dirty Read: là tình huống khi một transaction đọc dữ liệu chưa được commit. Ví dụ: Giả sử transaction 1 cập nhật một row và không được commit, trong khi đó, transaction 2 sẽ đọc row vừa được cập nhật. Nếu transaction 1 khôi phục thay đổi, transaction 2 sẽ đọc dữ liệu được coi là chưa từng tồn tại.
  • Non-repeatable Read: xảy ra khi một transaction đọc cùng một row hai lần và nhận được một giá trị khác nhau mỗi lần. Ví dụ: giả sử transaction T1 đọc dữ liệu. Do đồng thời, một transaction T2 khác cập nhật cùng một dữ liệu và commit, Bây giờ nếu transaction T1 đọc lại cùng một dữ liệu, nó sẽ lấy một giá trị khác.
  • Phantom Read: xảy ra khi hai query giống nhau được thực thi, nhưng các rows được truy xuất bởi hai truy vấn trên là khác nhau. Ví dụ: giả sử transaction T1 truy xuất một tập hợp các rows thỏa mãn một số tiêu chí tìm kiếm. Bây giờ, transaction T2 tạo một số hàng mới phù hợp với tiêu chí tìm kiếm cho transaction T1. Nếu transaction T1 thực hiện lại câu lệnh đọc các rows thì lần này nó sẽ nhận được một tập hợp các hàng khác.

II. Transaction Isolation Level

1. Read Uncommitted

Đây là mức cô lập thấp nhất. Ở cấp độ này, một transaction có thể đọc những thay đổi chưa được commit do các transaction khác thực hiện, do đó cho phép đọc sai. Ở cấp độ này, các transaction không bị cô lập với nhau.

Ví dụ:

-- Create sample table
CREATE TABLE Accounts (
    AccountID INT PRIMARY KEY,
    Balance DECIMAL(10,2)
);

INSERT INTO Accounts (AccountID, Balance) VALUES (1, 100.00);

-- Run T1, but not commit
-- Set New Balance = 50.00
START TRANSACTION;
UPDATE Accounts SET Balance = Balance - 50.00 WHERE AccountID = 1;

-- Run T2
-- Balance = 50.00
START TRANSACTION;
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT Balance FROM Accounts WHERE AccountID = 1;

2. Read Committed

Mức cô lập này đảm bảo rằng mọi dữ liệu đã đọc đều được commit tại thời điểm nó được đọc. Vì vậy nó không cho phép Dirty Read. Transaction  giữ khóa đọc hoặc ghi trên hàng hiện tại và do đó ngăn các transaction khác đọc, cập nhật hoặc xóa nó.

Ví dụ:

-- Create sample table
CREATE TABLE Accounts (
    AccountID INT PRIMARY KEY,
    Balance DECIMAL(10,2)
);

INSERT INTO Accounts (AccountID, Balance) VALUES (1, 100.00);

-- Run T1, but not commit
-- Set New Balance = 50.00
START TRANSACTION;
UPDATE Accounts SET Balance = Balance - 50.00 WHERE AccountID = 1;

-- Run T2
-- Balance = 100.00, not 50.00
START TRANSACTION;
SELECT Balance FROM Accounts WHERE AccountID = 1;
COMMIT;

3. Repeatable Read

Mức cô lập này đảm bảo rằng một transaction sẽ thấy cùng một dữ liệu trong suốt thời gian của nó, ngay cả khi các transaction khác thực hiện thay đổi dữ liệu. Tuy nhiên, vẫn có thể Phantom Read.

Ví dụ:

-- Create sample table
CREATE TABLE Accounts (
    AccountID INT PRIMARY KEY,
    Balance DECIMAL(10,2)
);

INSERT INTO Accounts (AccountID, Balance) VALUES (1, 100.00);

-- Run T1
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
START TRANSACTION;

-- 1st reading query
-- Balance = 100.00
SELECT Balance FROM Accounts WHERE AccountID = 1;

-- 2nd reading query 
-- Balance = 100.00, not 50.00
SELECT Balance FROM Accounts WHERE AccountID = 1;
COMMIT;

-- Run T2 after 1st reading query in T1
-- Balance = 50.00
START TRANSACTION;
UPDATE Accounts SET Balance = Balance - 50.00 WHERE AccountID = 1;
COMMIT;

4. Serializable

Đây là mức cô lập cao nhất trong đó transaction được thực hiện như thể đó là transaction duy nhất trong hệ thống. Tất cả các transaction phải được thực hiện tuần tự, điều này đảm bảo rằng không có lần Dirty Read, Non-repeatable Read, và Phantom Read.

Ví dụ:

  • TH 1: T1 chạy trước T2
-- Case 1: Run T1 before T2
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
START TRANSACTION;

-- Reading query
-- Balance = 100.00
SELECT Balance FROM Accounts WHERE AccountID = 1;

-- Writing query
-- New Balance = 200.00
UPDATE Accounts SET Balance = Balance + 100.00 WHERE AccountID = 1;

COMMIT;

-- Run T2
-- Blocking until T1 commit
-- New balance = 150.00
START TRANSACTION;
UPDATE Accounts SET Balance = Balance - 50.00 WHERE AccountID = 1;

COMMIT;
  • TH 2: T1 chạy sau T2
-- Case 1: Run T1 after T2
-- Blocking until T2 commit
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
START TRANSACTION;

-- Reading query
-- Balance = 50.00
SELECT Balance FROM Accounts WHERE AccountID = 1;

-- Writing query
-- New Balance = 150.00
UPDATE Accounts SET Balance = Balance + 100.00 WHERE AccountID = 1;

COMMIT;

-- Run T2
-- New balance = 50.00
START TRANSACTION;
UPDATE Accounts SET Balance = Balance - 50.00 WHERE AccountID = 1;

COMMIT;

Tổng kết

Ngoài các mức cô lập tiêu chuẩn, một số DBMS cũng có thể hỗ trợ các mức cô lập tùy chỉnh bổ sung hoặc các tính năng như SnapshotMulti-version concurrency control (MVCC) cung cấp các giải pháp thay thế cho các vấn đề được giải quyết bằng các mức cô lập tiêu chuẩn.

III. Ưu điểm và nhược điểm

1. Ưu điểm

  • Cải thiện tính đồng thời: Mức độ cô lập trong transaction có thể cải thiện tính đồng thời bằng cách cho phép nhiều transaction chạy đồng thời mà không can thiệp lẫn nhau.
  • Kiểm soát tính nhất quán của dữ liệu: Các mức cô lập cung cấp khả năng kiểm soát mức độ nhất quán của dữ liệu mà một ứng dụng cụ thể yêu cầu.
  • Giảm sự bất thường của dữ liệu: Việc sử dụng các mức cách ly có thể làm giảm sự bất thường của dữ liệu như dirty reads, non-repeatable reads, và phantom reads.
  • Tính linh hoạt: Việc sử dụng các mức cách ly khác nhau mang lại sự linh hoạt trong việc thiết kế các ứng dụng yêu cầu các mức độ nhất quán dữ liệu khác nhau.

2. Nhược điểm

  • Tăng chi phí: Việc sử dụng các mức cô lập có thể làm tăng chi phí vì hệ thống quản lý cơ sở dữ liệu phải thực hiện các kiểm tra bổ sung và thu được nhiều locks hơn.
  • Giảm tính đồng thời: Một số mức cô lập, chẳng hạn như Serializable, có thể làm giảm tính đồng thời bằng cách yêu cầu các transactions có được nhiều locks hơn, điều này có thể dẫn đến việc blocking.
  • Hỗ trợ hạn chế: Không phải tất cả các hệ thống quản lý cơ sở dữ liệu đều hỗ trợ tất cả các mức cô lập, điều này có thể hạn chế tính di động của các ứng dụng trên các hệ thống khác nhau.
  • Độ phức tạp: Việc sử dụng các mức cô lập khác nhau có thể tăng thêm độ phức tạp cho việc thiết kế các ứng dụng cơ sở dữ liệu, khiến chúng khó triển khai và bảo trì hơn.

IV. Kết luận

Các mức độ cô lập rất quan trọng trong việc duy trì tính nhất quán và tính toàn vẹn của dữ liệu trong DBMS. Bằng cách xác định mức độ cô lập mà các transaction  phải tuân thủ, các mức độ này giảm thiểu nguy cơ của các hiện tượng không mong muốn liên quan đến concurrency, đảm bảo kết quả của các transactions đáng tin cậy.

V. Tài liệu tham khảo