Active Records support optimistic locking if the field
lock_version
is present. Each update to the record increments
the lock_version column and the locking facilities ensure that records
instantiated twice will let the last one saved raise a StaleObjectError if
the first was also updated. Example:
p1 = Person.find(1) p2 = Person.find(1) p1.first_name = "Michael" p1.save p2.first_name = "should fail" p2.save # Raises a ActiveRecord::StaleObjectError
You’re then responsible for dealing with the conflict by rescuing the exception and either rolling back, merging, or otherwise apply the business logic needed to resolve the conflict.
You must ensure that your database schema defaults the lock_version column to 0.
This behavior can be turned off by setting
ActiveRecord::Base.lock_optimistically = false
. To override
the name of the lock_version column, invoke the
set_locking_column
method. This method uses the same syntax as
set_table_name
Source: show
# File rails/activerecord/lib/active_record/locking/optimistic.rb, line 44 def attributes_from_column_definition_with_lock result = attributes_from_column_definition_without_lock # If the locking column has no default value set, # start the lock version at zero. Note we can't use # locking_enabled? at this point as @attributes may # not have been initialized yet if lock_optimistically && result.include?(self.class.locking_column) result[self.class.locking_column] ||= 0 end return result end