Skip to main content

Command Palette

Search for a command to run...

Transaction Isolation Level - SERIALIZABLE

Published
3 min readView as Markdown

Đỉnh cao trong thế giới Isolation Level đó chính là SERIALIZABLE.
Nghe tên thôi đã thấy... lạnh gáy rồi 😎

Định nghĩa:

SERIALIZABLE = mọi transaction chạy như thể nó đang chạy lần lượt từng cái một, không ai chen vào.

Chuẩn luôn, không đùa đâu: SERIALIZABLE làm thế giới của ta an toàn như ngân hàng, nhưng bù lại, cũng đắt đỏ như ngân hàng vậy.

1. SERIALIZABLE là gì?

Nói ngắn gọn:

  • Không Dirty Read

  • Không Non-Repeatable Read

  • Không Phantom Read

  • Không Insert bậy, không Update lén, không Delete phũ.

Mọi transaction nhìn thấy y như là mình đang chạy một mình trên database này.
Không ai đẻ thêm bản ghi bất thình lình. Không ai bốc hơi bản ghi. Không ai sửa lén sau lưng.

Cảm giác?

“Mày vào quán gọi phở, nguyên cái quán đóng cửa phục vụ riêng mày.”

2. Tình huống dễ hiểu

Giả sử có bảng accounts:

idbalance
11000
22000

Transaction A:

START TRANSACTION;
SELECT SUM(balance) FROM accounts;
-- Thấy tổng tiền = 3000

Transaction B (ở ngoài):

INSERT INTO accounts (id, balance) VALUES (3, 5000);
COMMIT;

Nếu Isolation thấp (ví dụ READ COMMITTED), Transaction A sau đó:

SELECT SUM(balance) FROM accounts;
-- Thấy tổng tiền = 8000 (WTF??)

Nhưng nếu là SERIALIZABLE, thì:

  • Transaction B phải đợi Transaction A kết thúc mới được Insert.

  • Hoặc Transaction B bị lỗi (Serialization failure).

→ Không bao giờ có chuyện dữ liệu Transaction A đọc bị thay đổi giữa chừng.

3. Cách mà SERIALIZABLE "chơi đẹp"

  • Database khóa dữ liệu kỹ như ngân khố.

  • Hoặc dùng snapshot + validation: kiểm tra xem có ai phá bĩnh giữa chừng không.

  • Nếu có, Transaction fail liền! ("Serialization Error" quen thuộc nè)

4. Những lưu ý sống còn

Câu hỏiTrả lời
Dùng SERIALIZABLE có chậm không?Chậm vãi. Vì nhiều transaction phải đợi nhau, hoặc bị fail, retry.
Có deadlock không?Có, vì nhiều transaction ôm khóa chết chặt.
Khi nào mới nên xài?Khi dữ liệu rất nhạy cảm (ví dụ: ngân hàng, chứng khoán) và không thể chịu được lỗi dù là nhỏ nhất.
Có cách nào bớt đau không?Có. Xài SERIALIZABLE chỉ ở vài transaction cần độ chính xác tuyệt đối. Chứ để default vậy là database khóc đó.

5. Ví dụ chiến đấu thực tế

Scenario:
Đếm số lượng đơn hàng giá > 500.

Transaction A:

START TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SELECT COUNT(*) FROM orders WHERE price > 500;
-- Thấy 10 đơn hàng

Transaction B:

INSERT INTO orders (id, price) VALUES (11, 600);
-- Bình thường => đẻ thêm một đơn thỏa điều kiện

Trong SERIALIZABLE, Transaction B sẽ:

  • Chờ Transaction A xong.

  • Hoặc bị lỗi: ERROR: could not serialize access due to concurrent update.

→ Không bao giờ có vụ Transaction A thấy 10 đơn, mà lát sau thấy 11 đơn.

6. Tóm gọn

Mức độ nguy hiểmTrạng thái
Dirty ReadKhông
Non-Repeatable ReadKhông
Phantom ReadKhông
Insert lén, Update phũKhông
Hiệu năngRùa bò

7. Nói nhỏ

  • Đừng bật SERIALIZABLE cho toàn bộ hệ thống Production (unless muốn server ngáp ngáp).

  • Chỉ dùng cho các transaction thật sự cần chính xác từng đồng xu.

  • Nên biết retry Transaction khi bị serialization error.

Chốt bài

SERIALIZABLE – đỉnh cao của cô đơn trong thế giới database.

Càng cô đơn, càng an toàn, càng mắc tiền.

Nhưng nhớ, xài đúng lúc thì nó cứu ta. Xài bừa bãi thì nó giết server ta.

More from this blog

Engineer log

62 posts