Tìm ví dụ thực tế về tính ACID và BASE của database

Em muốn hỏi về tính chất ACID và BASE của mỗi transaction khi access database chứ không phải tính axit, bazo, độ pH của hợp chất hóa học. Mỗi transaction CSDL quan hệ SQL (MS SQL server) thì phải có 4 tính chất ACID còn CSDL noSQL (MongoDB) thì phải có 4 tính chất BASE.

Theo lý thuyết thì :

  • ACID là Atomic - Consistent - Isolated - Durable.
  • BASE là Basically Available - Soft state- Eventual consistency.

Định nghĩa thì em có đọc nhiều trên mạng rồi, mà chả hiểu gì cả.

Em chỉ tìm được 1 trường hợp thực tế cho thấy rõ các tính chất:

  • Atomic: giao dịch chuyển tiền là 1 transaction gồm nhiều giao tác (check số dư, trừ tiền A, cộng tiền B, gửi thông báo, …). Transaction này hoặc thành công nếu tất cả giao tác đó thành công hoặc thất bại nếu chỉ một giao tác bất kỳ thất bại. Nếu trường hợp thất bại xảy ra thì CSDL phải có cơ chế rollback để khôi phục về trạng thái ban đầu xem như chưa có chuyện gì xảy ra (tiền của A vẫn còn nguyên).
  • Durable: Không biết em có hiểu sai không, nhưng trường hợp này là điều hiển nhiên của database (nó liên quan đến tính chất của ổ đĩa), dữ liệu đã lưu thành công rồi thì nó sẽ tồn tại vĩnh viễn, nó chỉ mất khi có người cố tình xóa hoặc ổ đĩa cứng bị hỏng. Không khác gì lưu một file video, mp3 thông thường cả => Nếu đúng thì database có paradigm là document oriented (điển hình là mongoDB) cũng có tính chất này mà chứ đâu riêng gì RDB mới có (Trừ trường hợp DB lưu trên RAM như redis)?

Em muốn xin 5 ví dụ của các trường hợp còn lại ạ.

Khi so sánh ACID và BASE thì người ta thường nhắc tới tính nhất quán (consistency), vậy tính nhất quán ở đây cụ thể có nghĩa là gì? Có phải đang nói đến số lượng thuộc tính của một thực thể nào đó, CSDL RDB có thiết kế bảng, scheme từ trước nên cho ra các row (object trong thực tế) đồng nhất về thuộc tính. Còn MongoDB các object được sinh ra cùng một “cái gì đó tương tự class :v” nếu có số lượng thuộc tính khác nhau thì vẫn hợp lệ?

Em cảm ơn nhiều.

P/S: em là sinh viên đã sử dụng MS SQL server và MySQL được 1 năm, MongoDB dùng được vài tháng.

1 Like

Uhm, câu hỏi của cậu thú vị đó! :smile:
Tớ sẽ chia câu trả lời của tớ thành các section. Cậu theo dõi và đọc phần cậu muốn hiểu nha! :smile:

Atomic

Về ví dụ Atomic, cậu hiểu đúng tính chất đó rồi.

Durability

Về Durability, cậu hiểu cơ bản khái niệm rồi. Tuy nhiên, tớ không nghĩ NoSQL durable đâu :smile:
NoSQL như cậu đã biết, thiết kế theo BASE. Vì lẽ đó, khi cậu gửi một request thay đổi/thêm/xóa dữ liệu tới NoSQL, cho dù NoSQL có trả lời cậu “OK”, nhưng nó không đồng nghĩa với việc dữ liệu của cậu đã được persist trên đĩa (nó sẽ được, nhưng ở một thời điểm nào đó trong tương lai).
Thiết kế này sẽ cho cậu một vài hệ quả:

  1. NoSQL nhanh hơn SQL trong thời gian phản hồi.
    Đó là selling point của NoSQL, khi cậu không tốn cost persist dữ liệu vào disk (vốn đắt đỏ), mà thực hiện nó một cách bất đồng bộ về sau.
  2. Cậu có thể đã nhận thấy, có 1 khoảng thời gian từ lúc NoSQL trả về “OK”, tới lúc NoSQL thực sự persist dữ liệu vào disk.
    Chuyện gì sẽ xảy ra nếu như server của cậu gặp vấn đề, như crash NoSQL, mất điện, etc? :smile:
    Dữ liệu chưa kịp persist vào disk sẽ bị mất ở trường hợp này, trong khi dữ liệu của SQL vẫn sẽ còn. Đấy là khả năng durability.
    Vì vậy, trong TH thiết kế của cậu yêu cầu cao với tính nhất quán dữ liệu, cậu buộc phải cân nhắc SQL hơn là NoSQL. Sếp nào chịu được việc khi cậu gọi tới database để trừ tiền khách hàng, DB trả lời hoàn thành, nhưng cuối cùng, tiền thực ra chưa chắc sẽ bị trừ trong một số TH chứ? :smile:

Vậy nên, MongoDB hay các NoSQL khác đều không thể đảm bảo durability trong mọi TH đâu.

Consistency

Tính nhất quán, thật không may, cậu không hiểu đúng rồi.
Để hiểu về tính nhất quán, cậu cần hiểu 1 khái niệm, đó là data integrity - tính toàn vẹn dữ liệu. Tớ sẽ giải thích bằng ví dụ nhé! :smile:
Thử tưởng tượng cậu có một model mô phỏng dữ liệu thuộc về 1 giao dịch ngân hàng trong app của cậu. Model đó bao gồm:

  • Thông tin tài khoản gửi (số tài khoản, các ràng buộc như hạn mức, khả năng thực hiện giao dịch, số dư hiện tại, đơn vị tiền tệ…)
  • Thông tin tài khoản nhận (tương tự như tk gửi).
  • Số tiền (khoản tiền, đơn vị tiền tệ, tỷ giá tại thời điểm gửi…)

Cậu hẳn nhiên cần thiết kế database schema để lưu thông tin trên. Nó thường được lưu trữ ở các bảng/collection/khái niệm tương tự nào đó ở CSDL.
Giờ, nếu cậu cần chuyển 1 khoản tiền từ tài khoản người gửi sang tài khoản người nhận, cậu cần:

  • Kiểm tra số dư ở tài khoản gửi
  • Trừ tiền ở tài khoản gửi
  • Cộng tiền ở tài khoản nhận

Chuyện gì sẽ xảy ra nếu như sau khi cậu trừ tiền ở tài khoản gửi, nhưng gặp lỗi khi đang cố cộng tiền ở tài khoản nhận?

  • Nếu cậu không rollback lại trạng thái cũ, cậu sẽ có một model không toàn vẹn: số tiền gửi đã trừ, nhưng bên còn lại chưa nhận được.
  • Nếu cậu không dùng SQL transaction, khoảng thời gian giữa thời điểm trừ tiền ở tk gửi và cộng tiền ở tk nhận, model của cậu cũng không toàn vẹn về mặt logic.

Đó là consistency :smile: Về cơ bản, DB đảm bảo tính chất này sẽ đảm bảo cậu luôn có model toàn vẹn về mặt logic. Không thời điểm nào model của cậu bị sai về mặt logic cả :smile:

Database theo nguyên tắc BASE sẽ không thể đảm bảo tính toàn vẹn dữ liệu tại mọi thời điểm. Vậy nên, nếu cậu cần bảo vệ data integrity nghiêm ngặt (chẳng hạn, các thao tác liên quan tới tiền), cậu buộc phải cân nhắc DB có tính chất ACID, hoặc sử dụng NoSQL mà hi sinh availability (see CAP theorem).

Isolation

Tính chất này đảm bảo cho cậu các transaction khác nhau chạy độc lập với nhau. Điều đó có nghĩa là, việc đọc dữ liệu từ DB ở transaction này không bị ảnh hưởng bởi việc ghi dữ liệu ở transaction khác khi việc ghi này chưa được commit.
Với ví dụ ở phần “Consistency”, cậu có thể thấy nếu có 2 transaction cùng thực hiện chuyển khoản, 2 transaction này không nên ảnh hưởng lẫn nhau ở bất cứ thao tác đọc/ghi nào.

Liên quan tới tính chất này, cậu nên tìm hiểu thêm về transaction isolation level. Kiến thức này có thể hơi advance chút, nhưng nếu được, cậu nên biết nó có tồn tại, cho công việc của cậu ở tương lai :smile:


Tớ nghĩ qua ví dụ trên, cậu có thể hiểu hơn về ACID, thậm chí cả BASE. Nếu cậu có vấn đề gì về việc hiểu 2 tính chất này, cho tớ biết nhé! :smile:

6 Likes

Dạ anh ơi cho em hỏi về trường hợp này có bị vi phạm tính nhất quán của dữ liệu không? Nếu không thì gọi là gì?
Ví dụ có một trường đại học, thầy hiệu trưởng muốn query database trường report chính xác số lượng sinh viên hiện tại đang theo học tại trường. Mà mỗi bộ phận lại đưa ra số liệu khác nhau. VD:

  • Hỏi phòng tài chính hiện tại trường có bao nhiêu sinh viên?
    ==> Phòng tài chính dựa vào số lượng sinh viên đã đóng tiền học phí để trả lời là 1000 sinh viên đã đóng học phí nên hiện tại có 1000 sinh viên.
  • Nếu hỏi phòng đào tạo trường có bao nhiêu sinh viên?
    ==> Phòng đào tạo kiểm tra thấy hệ thống có 1500 sinh có thời khóa biểu, được xếp lớp nên trả lời là 1500.
  • Cũng câu hỏi đó mà với ban tuyển sinh.
    ==> Ban tuyển sinh sẽ trả lời là 2000 sinh viên, vì đầu năm học đã duyệt 2000 hồ sơ ứng tuyển hợp lệ.
  • Nếu hỏi các thầy chủ nhiệm.
    ===> Sau khi cộng danh sách điểm danh mỗi buổi thì thống kê lại chỉ có 800 sinh viên điểm danh đầy đủ (những em còn lại mặc dù có tên trong danh sách nhưng vắng nên không biết còn đi học hay đã nghỉ luôn).
  • Nếu lấy dữ liệu từ máy quẹt thẻ trước cổng bảo vệ
    ===> Bác bảo vệ kiểm tra máy chấm công thì xuất report: “chỉ có 500 sinh viên ra vào cổng trường thường xuyên thôi, những em còn lại từ đầu năm tới giờ chưa thấy bước vào cổng trường”

Giả sử những số liệu đó là thật, không có ai gian dối hết. Vậy cuối cùng ngôi trường này hiện tại có bao nhiêu sinh viên? Thầy hiệu trưởng biết tin vào số liệu nào khi cấp dưới mỗi người thống kê ra một kiểu? Vậy thông tin tổng số sinh viên đang còn học hiện tại là chưa nhất quán đúng không anh?

Không, vì mỗi bác đều dùng 1 database khác nhau với các tiêu chí lọc cũng khác nhau nên kết quả cho ra khác nhau là bình thường

4 Likes

Như @qloved nói, mỗi hệ thống có một concern khác nhau, nên số liệu của mỗi hệ thống cũng có ý nghĩa khác nhau. Các hệ thống cậu đề cập đều không chính xác trong việc trả lời câu hỏi “có bao nhiêu sinh viên trong trường?”.
Về cơ bản, ví dụ của cậu có lẽ không chính xác lắm về TH thực tế của việc số liệu không nhất quán đâu. Nếu cậu có ví dụ nào về 2 hệ thống cùng một concern, nhưng thiếu sự đồng bộ giữa 2 hệ thống, thì sẽ chính xác hơn.

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?