From 7afbc89c37e56531c9ef4e34369e329aab1b21de Mon Sep 17 00:00:00 2001 From: Olek Janiszewski Date: Wed, 18 Jan 2012 23:03:55 +0100 Subject: Add ActiveRecord::Base#with_lock Add a `with_lock` method to ActiveRecord objects, which starts a transaction, locks the object (pessimistically) and yields to the block. The method takes one (optional) parameter and passes it to `lock!`. Before: class Order < ActiveRecord::Base def cancel! transaction do lock! # ... cancelling logic end end end After: class Order < ActiveRecord::Base def cancel! with_lock do # ... cancelling logic end end end --- activerecord/test/cases/locking_test.rb | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/locking_test.rb b/activerecord/test/cases/locking_test.rb index 0c458d5318..807274ca67 100644 --- a/activerecord/test/cases/locking_test.rb +++ b/activerecord/test/cases/locking_test.rb @@ -388,6 +388,26 @@ unless current_adapter?(:SybaseAdapter, :OpenBaseAdapter) || in_memory_db? end end + def test_with_lock_commits_transaction + person = Person.find 1 + person.with_lock do + person.first_name = 'fooman' + person.save! + end + assert_equal 'fooman', person.reload.first_name + end + + def test_with_lock_rolls_back_transaction + person = Person.find 1 + old = person.first_name + person.with_lock do + person.first_name = 'fooman' + person.save! + raise 'oops' + end rescue nil + assert_equal old, person.reload.first_name + end + if current_adapter?(:PostgreSQLAdapter, :OracleAdapter) def test_no_locks_no_wait first, second = duel { Person.find 1 } -- cgit v1.2.3