In pessimistic locking a particular row in the database is exclusively locked so that other updates on the same record are blocked . This mechanism has the advantage that when a certain operation is going on the selected row other user cannot read or write on that particular row. Operations using pessimistic locking is usually done within a transaction.
Example:
Payment.transaction do
record1 = Payment.where(:user_id => 1).lock(true).first
record2 = Payment.where(:user_id => 2).lock(true).first
record1.balance -= 100
record1.save!
record2.balance += 100
record2.save!
end
If we want we can pass raw sql for locking the records like we can use LOCK IN SHARE MODE of mysql to restrict the locking to only write mode.
Payment.transaction do
record1 = Payment.where(:user_id => 1).lock("LOCK IN SHARE MODE").first
record2 = Payment.where(:user_id => 2).lock("LOCK IN SHARE MODE").first
record1.balance -= 100
record1.save!
record2.balance += 100
record2.save!
end
This way other users can read the data but cannot update it.
We can also lock the record on the go if we have already retrieved it from database.
record = Payment.first
record.with_lock do
# This block is called within a transaction,
# record is already locked.
record.balance += 100
record.save!
end
One downside of pessimistic locking is that the record remains locked until a particular operation is completed on it. This makes all the other processes on this record to wait until the current one is over. Thus the site becomes slow.
0 Comment(s)