[Pessimistic locking] Xử lí dữ liệu bất đồng bộ trong thực tế

image 54 - quochung.cyou PTIT

Pessimistic locking là gì?

Đọc vấn đề xảy ra về dữ liệu đồng thời tại : http://quochung.cyou/optimistic-locking-xu-li-du-lieu-bat-dong-bo-trong-thuc-te/

Pessimistic locking (Khoá bi quan) là một chiến thuật xử lí có thể tổng quát rằng, giả dụ, bạn có một tập dữ liệu đang bị truy cập đồng thời, người đầu tiên truy cập sẽ khoá tập dữ liệu này lại, độc quyền sửa đổi nó, cho đến khi phiên đó hoàn thành. Điều này đảm bảo dữ liệu sẽ chuẩn xác hơn khoá lạc quan, nhưng cũng có thể tạo ra Deadlock

Ví dụ bài toán

  • Bạn đang chơi một con game sinh tồn, có một chiếc rương chứa đồ chung mà hai người chơi đều có thể mở, nhưng nếu cả hai cùng mở, người này lấy đồ, người kia lại cho đồ vào, đôi khi dữ liệu sẽ bị loạn
  • Khoá bi quan sẽ xử lí như sau
  • Khi người chơi A mở rương, khoá rương lại. Lúc này người chơi khác ấn vào rương sẽ bị thông báo như dạng “rương đang được mở bởi người khác”, và không thể truy cập cho đến khi người chơi A đóng rương.
image 56 - quochung.cyou PTIT
image 57 - quochung.cyou PTIT

Deadlock

  • Deadlock xảy ra khi hai phiên không thể tiến triển được nữa, vì cùng phụ thuộc vào nhau chờ phía bên kia mở khoá, có thể xem hình dưới đây
image 58 - quochung.cyou PTIT
  • Ta có một database post chứa các bài viết. Trong đó có 1 bài viết id 1 và title là “Transaction”
  • Ngoài ra ta có 1 post chứa post_detail, là nội dung bài viết, số lượng like comment, …
  • Alice đầu tiên truy cập vào bảng post_detail, cập nhật số lượng like comment. Lúc này bảng post_detail thay đổi “người thay đổi cuối” thành Alice. Alice lock bảng post_detail
  • Lúc này Bob cũng truy cập vào bảng post, đổi tên nó thành thứ khác. Bob lock bảng post
  • Do bảng post và postdetail liên kết với nhau, lúc này ở phiên của Bob sẽ gọi về post_detail của post id 1 để thay đổi “người thay đổi” thành Bob. Tuy nhiên, nó đang bị khoá bởi Alice, vì vậy phải chờ Alice xong đã
  • Phía Alice lúc này cũng cập nhật lên bảng post, nhưng nó lại bị khoá bởi Bob, nên cũng phải đợi Bob xong đã
  • => Điều này trở thành vòng tuần hoàn vô hạn, cho đến khi hệ quản trị cơ sở dữ liệu có cơ chế phát hiện ra, và huỷ cả 2 phiên.

Deadlock ở mọi nơi: hệ điều hành, trong code đa luồng, ..

image 59 - quochung.cyou PTIT
  • Deadlock không chỉ xảy ra trong database, nó có thể xảy ra trong mọi hệ thống. Trong hệ điều hành, trong …., chỉ cần nếu chúng có thể truy cập từ nhiều nguồn cùng lúc
  • Ví dụ, đa luồng trong Java cũng có thể tạo deadlock khi 2 luồng cùng đợi nhau chứ không ai chạy trước

Cách xử lí

  • Khi Alice thực hiện khoá post, ta có thể khoá luôn cả post_Detail và các bảng liên quan
  • Hệ thống của ta cần có cơ chế phát hiện deadlock, ví dụ lock chờ đợi quá lâu, …

Đọc thêm:

[Optimistic locking] Xử lí dữ liệu bất đồng bộ trong thực tế

image 30 - quochung.cyou PTIT

Optimistic locking là gì?

Đây là một kĩ thuật xử lí vấn đề khi người dùng cùng làm việc trên một tập dữ liệu, nhưng sẽ không ảnh hưởng đến nhau. Nói cách khác, không có một khoá hay vấn đề gì ngăn cản người dùng cả, chúng ta chỉ kiểm tra lazy xem đang có một phiên nào khác đang sửa tập dữ liệu này không. Nếu có, ta sẽ rollback lại dữ liệu

Bài toán thực tế

  • Giả sử, bạn đang làm việc trên một bài toán khá đơn giản: một cửa hàng bán đồ điện tử. Nhiệm vụ của bạn là một giao diện admin để có thể lấy toàn bộ sản phẩm, thêm mới, cập nhật vài sản phẩm nào đó, xoá vài sản phẩm đi. Một bài toán CRUD đơn giản.
optimisticlocking - quochung.cyou PTIT
  • Lúc này, ta có 2 nhân viên đang trực ca và sử dụng hệ thống – Alice và Bob. Một ngày đẹp trời, Alice mới nhập kho vài chiếc màn máy tính phiên bản mới “Acer 2023”, cô muốn sửa tên “Acer 2022” trong sản phẩm cửa hàng thành “Acer 2023”. Đúng lúc này, Bob cũng đang muốn sửa tên của sản phẩm “Acer 2022” một cách fancy hơn, như là “Acer 2022 144hz”.

Quá trình xảy ra như sau:

  • Alice mở thông tin của món hàng, mở lên giao diện sửa tên. Bỗng nhiên, máy pha cà phê của cô báo hoàn thành, cô lập tức chạy đi lấy cà phê
  • Ở phía Bob, anh cũng đang mở thông tin món hàng “Acer 2022”, sửa tên thành “Acer 2022 144hz”, sau đó đi chơi
  • Alice quay trở lại, cô cũng nhập tên “Acer 2023”, sau đó ấn nút save
  • Bob đi chơi về và: ủa? sao lại thành tên này rồi?. Anh hỏi Alice thì cô cũng một mực khẳng định là tên hiển thị trong giao diện sửa của cô lúc sửa là “Acer 2022”, chứ chưa phải là “Acer 2022 144hz”

Vậy ai là người sai ở đây?

  • Là Alice, người ấn save lần cuối
  • Hay là Bob, người ấn đầu tiên?

Để xử lí vấn đề này, Optimistic locking đưa ra cách giải quyết là: các user cần được cập nhật rằng tập dữ liệu đã thay đổi

Một vài ví dụ có thể bạn từng thấy trong các ứng dụng về Optimistic locking

  • Bạn đang ở màn hình chọn voucher của shopee, sau khi chọn xong và chuẩn bị thanh toán. Lúc ấn thanh toán, bạn được báo “một vài voucher đã hết/thay đổi, vui lòng xem lại”
  • Bạn đang xem giá xe ở Grab, thì có thông báo yêu cầu reload lại do giá đã thay đổi
  • Bạn xem một post ở Facebook, lúc viết comment thì có thông báo “bài viết có thể không tồn tại nữa”
  • Khi bạn thực hiện commit

Các phase của Optimistic locking

  • Lưu lại timestamp, thời gian cuối khi mà một phiên bắt đầu
  • Bắt đầu sửa dữ liệu
  • Validate kiểm tra lại, kiểm tra xem thời gian lần cuối lưu ở phía client có giống với thời gian ở phía database không
  • Nếu không có conflict xảy ra, cập nhật mọi dữ liệu. Còn không thì resolve nó, có thể là huỷ phiên hiện tại, hoặc cho phép merge, ….
image 31 - quochung.cyou PTIT

Áp vào bài toán của chúng ta, ta có flow như sau

  • Alice thực hiện sửa ở phía local của Alice, ở database lúc này lưu “số phiên bản” của món đồ này là 1
  • Bob thực hiện sửa, sau đó lưu lại. Database cập nhật phiên bản lúc này đã là “2”
  • Alice ấn nút lưu, phát hiện phiên bản sai lệch, đưa ra cách xử lí nào đó cho người dùng

Tổng kết

Optimistic locking ngăn các vấn đề conflict dữ liệu xảy ra bằng cách kiểm tra conflict, sau đó tạo ra các cách resolve nó (merge, bỏ phiên, …)

  • Nó được gọi là Optimistic locking (khoá lạc quan)…. vì chúng ta lạc quan là khả năng conflict khá ít xảy ra
  • Phù hợp với nhiều món hàng, record và ít nguwofi dùng
  • Cho phép 1 cách nhiều người dùng làm trên 1 dữ liệu
  • Tốn ít công sức hơn, không cần khoá, …
  • Nhưng nếu conflict xảy ra, thường user sẽ phải làm lại phiên hoàn toàn …

Tham khảo:

Đọc thêm: