Cả hai đều ngăn race condition khi nhiều user sửa cùng record.
Optimistic Locking (default khi có cột lock_version):
- Không lock DB. Rails gắn lock_version vào record. Khi save, kiểm tra version có khớp không — nếu user khác đã sửa trước → raise ActiveRecord::StaleObjectError.
- Tốt cho trường hợp conflict ít xảy ra.
ruby
# Migration: add_column :products, :lock_version, :integer, default: 0
product = Product.find(1) # lock_version = 5
# ... user khác cũng đang sửa ...
product.update!(name: "New") # raise StaleObjectError nếu version đổiPessimistic Locking (DB-level lock):
- Dùng SQL SELECT ... FOR UPDATE — record bị lock cho đến khi transaction kết thúc.
ruby
Product.transaction do
product = Product.lock.find(1) # SELECT ... FOR UPDATE
product.decrement!(:stock)
endDùng Pessimistic khi conflict xảy ra thường xuyên (e.g. trừ kho).
Optimistic khi conflict hiếm.