0

To get a better understanding of pessimist locking (with InnoDB), I tried to run this code in my Rails application:

Thread.new do
  Account.transaction do
    account = Account.lock(true).first
    account.balance += 250
    account.save!
  end
end

Thread.new do
  Account.transaction do
    account = Account.lock(true).first
    account.balance += 500
    account.save!
  end
end

It actually works, account.balance then contains 750, then 1500 on the next hit. Without locking, it just takes the last thread into consideration and the result is 500.

Is that a dumb test to try out the difference between locking or not? I think I understand the principle of pessimist locking, but not sure though.

Zakari
  • 1
  • 1

1 Answers1

2

This test does allow you to observe pessimistic locking behaviour, but when you remove locks it doesn't switch to optimistic locking. It just does no locking at all.

Also, to be more idiomatic you could do this:

Thread.new do
  account = Account.first
  account.with_lock do
    account.balance += 250
    account.save!
  end
end

with_lock starts a transaction and acquires a lock in one go.

To observe optimistic locking behaviour you need lock_version field to be present in your model. Rails will then do record version check automatically and throw ActiveRecord::StaleObjectError on conflict.

Nic Nilov
  • 5,056
  • 2
  • 22
  • 37