Thuở sơ khai những năm 1970, các vị tiền bối đã sáng lập ra một môn phái tên là RDBMS. Và mỗi lần nhắc đến môn phái đó chắc hẳn các thế hệ hậu bối sẽ nghe lời đồn về ACID. Trước khi mò mẫm nét đẹp của ACID trong cõi giới đó, chúng ta lại không thể quên chiêu thức nổi tiếng mang tên Transaction. Vậy tóm lại transaction và ACID là gì ? Tại sao cần phải biết những thứ này ? Vì trong các buổi giao chiến (phỏng vấn), những thứ này sẽ giúp ích được mình.
1. Chiêu thức Transaction là gì ?
Hiểu một cách ngắn gọn, transaction là một tập hợp những câu lệnh truy vấn. Lấy ví dụ: A chuyển 10.000 đồng cho B => hệ thống trừ tiền A => hệ thống cộng tiền B. Đó là 1 transaction được chúng ta biểu diễn bằng những câu query bên dưới khi thao tác với database.
Và nỗi đau bắt đầu từ đây, khi chiêu thức tối cao này đi không đúng bí kíp ACID sẽ làm cho người sử dụng lạc lối gặp những hậu quả khó lường.
2. Bí kíp ACID có gì ?
Giống như cái tên của nó tuy ngắn gọn 4 chữ nhưng vô cùng bí hiểm, mình cùng mò mẫm nét đẹp của từng loại nha.
A - Atomicity - Tính đơn vị
Ông bà xưa có câu "Một con ngựa đau cả tàu bỏ cỏ", đây là minh chứng rõ ràng nhất cho tính đơn vị. Khi một tập hợp các lệnh truy vấn của transaction bắt đầu chạy, yêu cầu tất cả phải success hết, chỉ cần có một lệnh failed thì toàn bộ transaction sẽ không được thực thi. Trong ví dụ chuyển tiền trên cũng vậy, giao dịch đang phát sinh, đùng phát xui, hệ thống cúp điện, rồi giờ sao ta ? Người B thì chưa nhận được tiền còn người A thì bị trừ rồi.
Đang chạy giữa chừng chưa kịp commit, db crash một phát, hú hồn data còn nguyên và số dư không bị thay đổi gì hết.
C - Consistency - Tính nhất quán
Hiểu một cách ngắn gọn chính là dữ liệu sẽ luôn được đồng nhất xuyên suốt quá trình truy vấn database. Mình lấy ví dụ như update vào tài khoản của user_id = 1 số tiền cộng thêm là 20000:
Khi client gửi request đến db để update số dư tài khoản của user_id = 1, transaction đang thực thi thì ngay thời điểm này, lại có một request đến lấy thông tin tài khoản của user_id, lúc này để dữ liệu đảm bảo tính đồng nhất thì kết quả số dư vẫn sẽ không thay đổi.
Tuy nhiên, cuộc đời vốn không đẹp như vậy, khi một hệ thống phát triển mạnh, lượng user tăng cao sẽ sinh ra bài toán về scale database. Cả NoSQL và SQL đều đối mặt vấn đề consistence dữ liệu khi giải bài toán scaling. Lấy ví dụ một hệ thống scale ngang với mô hình master - slaves (master: ghi dữ liệu, slaves: đọc dữ liệu). Khi master chưa sync data về các slave xong thì vô tình có 1 request gửi đến đọc dữ liệu cũ thì toang.
Cuộc đời vốn phải có đánh đổi, quyết định là tùy vào từng nhu cầu và ngữ cảnh khác nhau của hệ thống: Strong consistency vs Eventual consistency
- Strong: Dữ liệu sẽ luôn nhất quán và được cập nhật mới nhất, bù lại sẽ có độ trễ cao.
- Eventual: Dữ liêu sẽ có thể không được cập nhật mới nhất, nhưng tốc độ truy vấn sẽ nhanh hơn.
I - Isolation - Tính độc lập
"Nước sông không phạm nước giếng" là ý nghĩa của isolation, hiểu đơn giản khi chúng ta có 2 transaction thực thi cùng lúc thì truy vấn thay đổi dữ liệu của transaction A sẽ không ảnh hưởng đến dữ liệu của transaction B. Như ví dụ bên dưới, mình thay đổi số lượng billings của user trong transaction 2 thì xui là số lượng billings của cùng user đó trong transaction 1 lúc này cũng bị thay đổi theo => Toang => Phải làm sao bây giờ ?
Đến đây, mình sẽ sử dụng tuyệt chiêu Repeatable reads trong binh pháp Isolation levels) để hóa giải trường hợp trên như sau
Như mọi người thấy, dữ liệu trong transaction 1 lúc này sẽ không bị ảnh hưởng bởi những thay đổi từ transaction 2 nữa rồi, vậy là thành công. Ngoài ra, còn rất nhiều chiêu thức khác về Isolation levels mà trong những bài viết sau mình sẽ cố gắng đi sâu hơn.
D - Durability - Tính bền vững
Giống như thị trường tài chính như chứng khoán hay crypto vậy, dù mai này có sập sàn thì tay phải vững để không mất tiền. Database cũng vậy, dù cho gặp một sự cố đột ngột làm sập hệ thống, thì dữ liệu cũng không được mất mát, không cho reset game. Mình lấy ví dụ như sau, khi mình đang thao tác trên 1 transaction thêm 1 account mới vào db, cùng lúc commit, mình tắt server đi, câu hỏi đặt ra vậy dữ liệu của mình còn toàn vẹn hay không ? Hay lúc mình tắt server thì mất luôn dữ liệu đã commit ?
Hooray!!! Account người dùng mới sau khi mình start lại database vẫn còn => Không bị mất mát dữ liệu.
3. Lời kết
Trời tạnh mưa, mình cũng dừng bút. Vậy là mình đã đi qua sơ nét cuốn bí kíp ACID rồi, tuy nhiên để thành thạo cần phải luyện tập nhiều hơn nữa. Phần hiểu biết ít ỏi của mình xin chia sẻ với các bạn, xin chân thành cảm ơn các bạn đã đọc. Bài viết chắc chắn còn rất nhiều thiếu sót, mình hi vọng được mọi người đóng góp và chia sẻ để mình có thể học hỏi và cải thiện nha.