Skip to content

Instantly share code, notes, and snippets.

@bensheldon
Created January 12, 2019 00:20
Show Gist options
  • Save bensheldon/3464eee4a02c2d974da239e978aff6b7 to your computer and use it in GitHub Desktop.
Save bensheldon/3464eee4a02c2d974da239e978aff6b7 to your computer and use it in GitHub Desktop.
Example of using Postgres advisory locks with Rails ActiveRecord
class Credential < ApplicationRecord
CredentialNotAvailableError = Class.new(StandardError)
def self.find_and_lock_credential
where("pg_try_advisory_lock(to_regclass('#{table_name}')::int, id::int)").first
end
def self.find_and_lock_credential!
find_and_lock_credential || raise(CredentialNotAvailableError)
end
def self.all_locks
connection.execute("SELECT * FROM pg_locks WHERE locktype = 'advisory' AND classid = to_regclass('#{table_name}')::int")
end
def locked?
self.class.connection.execute("SELECT 1 as one FROM pg_locks WHERE locktype = 'advisory' AND classid = to_regclass('#{self.class.table_name}')::int AND objid = #{id}").ntuples > 0
end
def unlock
self.class.connection.execute("SELECT pg_advisory_unlock(to_regclass('#{self.class.table_name}')::int, #{id}::int)").first["pg_advisory_unlock"]
end
def unlock!
unlock while locked?
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment