Pessimistic locking là một kỹ thuật trong lập trình để giữ an toàn khi truy cập cùng một tài nguyên từ nhiều người dùng hoặc quy trình khác nhau. Khi sử dụng pessimistic locking, bạn khóa tài nguyên trước khi sửa đổi nó và giải phóng khóa khi đã hoàn thành. Kỹ thuật này đảm bảo rằng chỉ một người dùng hoặc quy trình có thể truy cập và sửa đổi tài nguyên đó tại một thời điểm, tránh xung đột và mất dữ liệu.

Một ví dụ cụ thể về kỹ thuật pessimistic locking là khi có nhiều người cùng truy cập vào cùng một bản ghi trong cơ sở dữ liệu. Nếu không sử dụng pessimistic locking, có thể xảy ra tình huống một người đọc và một người sửa đổi dữ liệu cùng một lúc, dẫn đến dữ liệu bị mất hoặc bị xung đột.

Giả sử bạn có một bảng "orders" chứa các đơn hàng của khách hàng. Mỗi đơn hàng có một trạng thái (status), và bạn muốn cập nhật trạng thái của đơn hàng từ "chưa xử lý" (unprocessed) sang "đang xử lý" (processing) khi có một nhân viên đang xử lý đơn hàng đó. Trong trường hợp này, bạn có thể sử dụng pessimistic locking để đảm bảo rằng chỉ có một người sửa đổi trạng thái của một đơn hàng cùng một lúc.

Trong Laravel, bạn có thể triển khai pessimistic locking thông qua Eloquent ORM. Bạn có thể sử dụng phương thức lockForUpdate trên một truy vấn để khóa bản ghi cho đến khi giao dịch hoàn thành. Ví dụ, để khóa bản ghi với id là 1 trong bảng users, bạn có thể sử dụng mã sau đây:

$user = User::where('id', 1)->lockForUpdate()->first();

Trong trường hợp này, bản ghi được khóa cho đến khi giao dịch hoàn thành hoặc truy vấn được thực hiện. Bạn cũng có thể sử dụng sharedLock để khóa tài nguyên mà không ảnh hưởng đến các truy vấn khác trên tài nguyên đó.

Ví dụ:

$user = User::where('id', 1)->sharedLock()->first();

Phương thức sharedLock sẽ khóa tài nguyên cho đến khi giao dịch hoàn thành, nhưng cho phép nhiều truy vấn đọc tài nguyên đó cùng một lúc. 

Ngoài ra, Laravel cũng cung cấp các phương thức khác để áp dụng pessimistic locking. Ví dụ, bạn có thể sử dụng phương thức selectForUpdate để khóa các cột cụ thể trong bảng thay vì khóa toàn bộ bản ghi.

Ví dụ:

$user = User::where('id', 1)->select('name')->selectForUpdate()->first();

Phương thức này sẽ chỉ khóa cột `name` của bản ghi với id là 1.

Để sử dụng pessimistic locking trong Laravel, bạn cần chắc chắn rằng hệ thống cơ sở dữ liệu của bạn hỗ trợ khóa quét hoặc khóa chia sẻ để tránh các tình huống khóa không mong muốn. Ngoài ra, bạn nên sử dụng pessimistic locking chỉ khi cần thiết và đảm bảo rằng không có cách nào khác để giải quyết vấn đề tương tự.

Có một cách khác để triển khai pessimistic locking trong Laravel đó là sử dụng phương thức lockForUpdate trên Builder object. Phương thức này khóa toàn bộ bảng trước khi truy vấn dữ liệu.

Ví dụ:

$user = DB::table('users')->where('id', 1)->lockForUpdate()->first();

 

Điều quan trọng cần lưu ý khi sử dụng phương thức lockForUpdate là nó chỉ khóa bảng hiện tại và không thể khóa cột cụ thể. Do đó, nếu bạn chỉ muốn khóa một số cột, hãy sử dụng phương thức selectForUpdate hoặc khóa theo tên khóa chính (primary key) như trong ví dụ trước đó.

Ngoài ra, nếu bạn đang sử dụng Eloquent, bạn cũng có thể sử dụng phương thức lockForUpdate trên Model object (ORM).

Ví dụ:

$user = User::where('id', 1)->lockForUpdate()->first();

Phương thức này hoạt động tương tự như phương thức lockForUpdate trên Builder object. Nó sẽ khóa toàn bộ bảng và chặn các truy cập khác đến bảng cho đến khi khóa được giải phóng hoặc giao dịch kết thúc.

Trên đây là các cách triển khai pessimistic locking trong Laravel mà bạn có thể sử dụng. Hãy lựa chọn phương thức phù hợp với yêu cầu của bạn và đảm bảo rằng bạn sử dụng pessimistic locking với cẩn thận để tránh tình huống khóa không mong muốn và tăng hiệu suất của hệ thống.

Tổng kết, pessimistic locking là một kỹ thuật hữu ích để giữ an toàn khi truy cập tài nguyên được chia sẻ. Laravel cung cấp các phương thức khác nhau để triển khai pessimistic locking và bạn cần chọn phương thức phù hợp nhất với yêu cầu của bạn. Bạn cũng cần đảm bảo rằng bạn sử dụng pessimistic locking với cẩn thận để tránh tình huống khóa không mong muốn và tăng hiệu suất của hệ thống.




Các thành viên đã like bài viết: