aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/locking/pessimistic.rb
diff options
context:
space:
mode:
authorOlek Janiszewski <olek.janiszewski@gmail.com>2012-01-18 23:03:55 +0100
committerOlek Janiszewski <olek.janiszewski@gmail.com>2012-01-18 23:23:41 +0100
commit7afbc89c37e56531c9ef4e34369e329aab1b21de (patch)
treeb2647a40311d813c21712dd5f78fe53f7b76ede8 /activerecord/lib/active_record/locking/pessimistic.rb
parent423b2626d85f75bb5fec03909ff8963bded7c7d5 (diff)
downloadrails-7afbc89c37e56531c9ef4e34369e329aab1b21de.tar.gz
rails-7afbc89c37e56531c9ef4e34369e329aab1b21de.tar.bz2
rails-7afbc89c37e56531c9ef4e34369e329aab1b21de.zip
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
Diffstat (limited to 'activerecord/lib/active_record/locking/pessimistic.rb')
-rw-r--r--activerecord/lib/active_record/locking/pessimistic.rb22
1 files changed, 22 insertions, 0 deletions
diff --git a/activerecord/lib/active_record/locking/pessimistic.rb b/activerecord/lib/active_record/locking/pessimistic.rb
index 66994e4797..58af92f0b1 100644
--- a/activerecord/lib/active_record/locking/pessimistic.rb
+++ b/activerecord/lib/active_record/locking/pessimistic.rb
@@ -38,6 +38,18 @@ module ActiveRecord
# account2.save!
# end
#
+ # You can start a transaction and acquire the lock in one go by calling
+ # <tt>with_lock</tt> with a block. The block is called from within
+ # a transaction, the object is already locked. Example:
+ #
+ # account = Account.first
+ # account.with_lock do
+ # # This block is called within a transaction,
+ # # account is already locked.
+ # account.balance -= 100
+ # account.save!
+ # end
+ #
# Database-specific information on row locking:
# MySQL: http://dev.mysql.com/doc/refman/5.1/en/innodb-locking-reads.html
# PostgreSQL: http://www.postgresql.org/docs/current/interactive/sql-select.html#SQL-FOR-UPDATE-SHARE
@@ -50,6 +62,16 @@ module ActiveRecord
reload(:lock => lock) if persisted?
self
end
+
+ # Wraps the passed block in a transaction, locking the object
+ # before yielding. You pass can the SQL locking clause
+ # as argument (see <tt>lock!</tt>).
+ def with_lock(lock = true)
+ transaction do
+ lock!(lock)
+ yield
+ end
+ end
end
end
end