diff options
author | Ryuta Kamizono <kamipo@gmail.com> | 2019-02-21 21:09:05 +0900 |
---|---|---|
committer | Ryuta Kamizono <kamipo@gmail.com> | 2019-02-25 20:14:56 +0900 |
commit | 1d8fad6f903d5065911bea3409c7a9082f47d3f8 (patch) | |
tree | 8504ca8cc3a484cd32d46f133d578b45b3bc0206 /activerecord/test/cases/relation | |
parent | 67e20d1d4854d834e9e43e56486d37cd98983f0d (diff) | |
download | rails-1d8fad6f903d5065911bea3409c7a9082f47d3f8.tar.gz rails-1d8fad6f903d5065911bea3409c7a9082f47d3f8.tar.bz2 rails-1d8fad6f903d5065911bea3409c7a9082f47d3f8.zip |
Ensure `update_all` series cares about optimistic locking
Incrementing the lock version invalidates any other process's optimistic
lock, which is the desired outcome: the record no longer looks the same
as it did when they loaded it.
Diffstat (limited to 'activerecord/test/cases/relation')
-rw-r--r-- | activerecord/test/cases/relation/update_all_test.rb | 71 |
1 files changed, 63 insertions, 8 deletions
diff --git a/activerecord/test/cases/relation/update_all_test.rb b/activerecord/test/cases/relation/update_all_test.rb index bb6912148c..0500574f28 100644 --- a/activerecord/test/cases/relation/update_all_test.rb +++ b/activerecord/test/cases/relation/update_all_test.rb @@ -138,14 +138,6 @@ class UpdateAllTest < ActiveRecord::TestCase assert_equal new_time, developer.updated_at end - def test_touch_all_updates_locking_column - person = people(:david) - - assert_difference -> { person.reload.lock_version }, +1 do - Person.where(first_name: "David").touch_all - end - end - def test_update_on_relation topic1 = TopicWithCallbacks.create! title: "arel", author_name: nil topic2 = TopicWithCallbacks.create! title: "activerecord", author_name: nil @@ -186,6 +178,69 @@ class UpdateAllTest < ActiveRecord::TestCase end end + def test_update_all_cares_about_optimistic_locking + david = people(:david) + + travel 5.seconds do + now = Time.now.utc + assert_not_equal now, david.updated_at + + people = Person.where(id: people(:michael, :david, :susan)) + expected = people.pluck(:lock_version) + expected.map! { |version| version + 1 } + people.update_all(updated_at: now) + + assert_equal [now] * 3, people.pluck(:updated_at) + assert_equal expected, people.pluck(:lock_version) + + assert_raises(ActiveRecord::StaleObjectError) do + david.touch(time: now) + end + end + end + + def test_update_counters_cares_about_optimistic_locking + david = people(:david) + + travel 5.seconds do + now = Time.now.utc + assert_not_equal now, david.updated_at + + people = Person.where(id: people(:michael, :david, :susan)) + expected = people.pluck(:lock_version) + expected.map! { |version| version + 1 } + people.update_counters(touch: [time: now]) + + assert_equal [now] * 3, people.pluck(:updated_at) + assert_equal expected, people.pluck(:lock_version) + + assert_raises(ActiveRecord::StaleObjectError) do + david.touch(time: now) + end + end + end + + def test_touch_all_cares_about_optimistic_locking + david = people(:david) + + travel 5.seconds do + now = Time.now.utc + assert_not_equal now, david.updated_at + + people = Person.where(id: people(:michael, :david, :susan)) + expected = people.pluck(:lock_version) + expected.map! { |version| version + 1 } + people.touch_all(time: now) + + assert_equal [now] * 3, people.pluck(:updated_at) + assert_equal expected, people.pluck(:lock_version) + + assert_raises(ActiveRecord::StaleObjectError) do + david.touch(time: now) + end + end + end + # Oracle UPDATE does not support ORDER BY unless current_adapter?(:OracleAdapter) def test_update_all_ignores_order_without_limit_from_association |