Để khóa lạc quan, bạn cần xác định một số phương tiện để kiểm tra xem một hàng có thay đổi so với lần trước hay không. Ví dụ:chỉ cần thêm một số nhận dạng khác:
alter table regions_indexes add version_id integer default 1 not null;
Bây giờ ứng dụng đọc một số hàng, hiển thị dữ liệu cho người dùng và đợi cho đến khi nút được nhấp. Chúng ta phải nhớ giá trị của version_id
chúng tôi đã nhận.
Sau khi nút được nhấp, bạn thực hiện tất cả các tính toán cần thiết. Khi bạn đã sẵn sàng cập nhật hàng, bạn khóa hàng và kiểm tra xem version_id
Không thay đổi. Nếu chưa, hãy tăng version_id
và cam kết. Nếu có, thật xui xẻo --- bạn cần yêu cầu người dùng lặp lại thao tác này vì có người chạy nhanh hơn anh ta.
Nó có thể trông giống như thế này (trong mã giả):
-- remember version_id
select *
from regions_indexes
where id = ... and resource_type = ...;
-- wait for user click
-- you can wait for a long time, because no lock is yet acquired
...
update regions_indexes
set current_resource = current_resource - ..., version_id = version_id + 1
where id = ... and resource_type = ...
returning version_id;
if new_version_id = old_version_id + 1 then
-- success, commit
else
-- fail, rollback
end if;
Nhưng khóa lạc quan không hoạt động tốt trong tình huống đồng thời cao. Khi xung đột không phải là hiếm, bạn sẽ phải thường xuyên khởi động lại các giao dịch.