Module: ArLock

Included in:
ApplicationRecord
Defined in:
lib/extensions/ar_lock.rb

Instance Method Summary collapse

Instance Method Details

#lock(mode = :exclusive, timeout = 60.seconds) ⇒ Object

Creates a critical section around the specified block, in the style of Mutex#synchronize, by locking on the database record in SQL.

See ActiveRecord::Locking::Pessimistic#with_lock for details about

the original version of this method.
mode

:exclusive or :shared (or :EX or :SH). Default is :exclusive. :exclusive mode will prevent two database callers from entering

the block concurrently.

:shared mode will allow concurrent entry into the block, but will

escalate to an :exclusive lock when ActiveRecord issues an
update to the record.
timeout

The amount of time, in seconds, before the block is timed out.

This prevents the block from blocking others indefinitely.
Default is 60 seconds.

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/extensions/ar_lock.rb', line 17

def lock(mode = :exclusive, timeout = 60.seconds)
  lock = case mode
         when :shared,    :SH then ActiveRecordQueryParts.shared_row_lock
         when :exclusive, :EX then ActiveRecordQueryParts.update_row_lock
         else raise "unknown lock mode <#{mode.inspect}>"
         end

  transaction do
    _log.debug "Acquiring lock on #{self.class.name}::#{id}..."
    lock!(lock)
    _log.debug "Acquired lock"

    begin
      Timeout.timeout(timeout) { yield self }
    ensure
      _log.debug "Releasing lock"
    end
  end
end