aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/locking
diff options
context:
space:
mode:
authorRyuta Kamizono <kamipo@gmail.com>2018-03-03 18:44:09 +0900
committerRyuta Kamizono <kamipo@gmail.com>2018-03-05 09:52:58 +0900
commitae2d36cf21281f4b720332a086b021d867e80084 (patch)
tree9d5dd0ad9122535f9607273a948ea5e91e5c8bb2 /activerecord/lib/active_record/locking
parentea45d56d3d23e703b2866524202649e333fd7408 (diff)
downloadrails-ae2d36cf21281f4b720332a086b021d867e80084.tar.gz
rails-ae2d36cf21281f4b720332a086b021d867e80084.tar.bz2
rails-ae2d36cf21281f4b720332a086b021d867e80084.zip
Introduce `_update_row` to decouple optimistic locking concern from `Persistence` module
Diffstat (limited to 'activerecord/lib/active_record/locking')
-rw-r--r--activerecord/lib/active_record/locking/optimistic.rb31
1 files changed, 31 insertions, 0 deletions
diff --git a/activerecord/lib/active_record/locking/optimistic.rb b/activerecord/lib/active_record/locking/optimistic.rb
index 29735f5490..af361a8d2d 100644
--- a/activerecord/lib/active_record/locking/optimistic.rb
+++ b/activerecord/lib/active_record/locking/optimistic.rb
@@ -111,6 +111,37 @@ module ActiveRecord
end
end
+ def _update_row(attribute_names, attempted_action)
+ return super unless locking_enabled?
+
+ begin
+ locking_column = self.class.locking_column
+ previous_lock_value = read_attribute_before_type_cast(locking_column)
+ attribute_names << locking_column
+
+ self[locking_column] += 1
+
+ affected_rows = self.class._update_record(
+ attributes_with_values(attribute_names),
+ self.class.primary_key => id_in_database,
+ locking_column => previous_lock_value
+ )
+
+ if affected_rows != 1
+ raise ActiveRecord::StaleObjectError.new(self, attempted_action)
+ end
+
+ affected_rows
+
+ # If something went wrong, revert the locking_column value.
+ rescue Exception
+ self[locking_column] = previous_lock_value
+ raise
+ ensure
+ clear_attribute_change(locking_column)
+ end
+ end
+
def destroy_row
return super unless locking_enabled?