Struct sqlx_core::postgres::PgAdvisoryLock
source · pub struct PgAdvisoryLock { /* private fields */ }
Expand description
A mutex-like type utilizing Postgres advisory locks.
Advisory locks are a mechanism provided by Postgres to have mutually exclusive or shared locks tracked in the database with application-defined semantics, as opposed to the standard row-level or table-level locks which may not fit all use-cases.
This API provides a convenient wrapper for generating and storing the integer keys that advisory locks use, as well as RAII guards for releasing advisory locks when they fall out of scope.
This API only handles session-scoped advisory locks (explicitly locked and unlocked, or automatically released when a connection is closed).
It is also possible to use transaction-scoped locks but those can be used by beginning a
transaction and calling the appropriate lock functions (e.g. SELECT pg_advisory_xact_lock()
)
manually, and cannot be explicitly released, but are automatically released when a transaction
ends (is committed or rolled back).
Session-level locks can be acquired either inside or outside a transaction and are not tied to transaction semantics; a lock acquired inside a transaction is still held when that transaction is committed or rolled back, until explicitly released or the connection is closed.
Locks can be acquired in either shared or exclusive modes, which can be thought of as read locks and write locks, respectively. Multiple shared locks are allowed for the same key, but a single exclusive lock prevents any other lock being taken for a given key until it is released.
Implementations§
source§impl PgAdvisoryLock
impl PgAdvisoryLock
sourcepub fn new(key_string: impl AsRef<str>) -> Self
pub fn new(key_string: impl AsRef<str>) -> Self
Construct a PgAdvisoryLock
using the given string as a key.
This is intended to make it easier to use an advisory lock by using a human-readable string
for a key as opposed to manually generating a unique integer key. The generated integer key
is guaranteed to be stable and in the single 64-bit integer keyspace
(see PgAdvisoryLockKey
for details).
This is done by applying the Hash-based Key Derivation Function (HKDF; IETF RFC 5869) to the bytes of the input string, but in a way that the calculated integer is unlikely to collide with any similar implementations (although we don’t currently know of any). See the source of this method for details.
Example
use sqlx::postgres::{PgAdvisoryLock, PgAdvisoryLockKey};
let lock = PgAdvisoryLock::new("my first Postgres advisory lock!");
// Negative values are fine because of how Postgres treats advisory lock keys.
// See the documentation for the `pg_locks` system view for details.
assert_eq!(lock.key(), &PgAdvisoryLockKey::BigInt(-5560419505042474287));
sourcepub fn with_key(key: PgAdvisoryLockKey) -> Self
pub fn with_key(key: PgAdvisoryLockKey) -> Self
Construct a PgAdvisoryLock
with a manually supplied key.
sourcepub fn key(&self) -> &PgAdvisoryLockKey
pub fn key(&self) -> &PgAdvisoryLockKey
Returns the current key.
sourcepub async fn acquire<C: AsMut<PgConnection>>(
&self,
conn: C
) -> Result<PgAdvisoryLockGuard<'_, C>>
pub async fn acquire<C: AsMut<PgConnection>>( &self, conn: C ) -> Result<PgAdvisoryLockGuard<'_, C>>
Acquires an exclusive lock using pg_advisory_lock()
, waiting until the lock is acquired.
For a version that returns immediately instead of waiting, see Self::try_acquire()
.
A connection-like type is required to execute the call. Allowed types include PgConnection
,
PoolConnection<Postgres>
and Transaction<Postgres>
, as well as mutable references to
any of these.
The returned guard queues a pg_advisory_unlock()
call on the connection when dropped,
which will be executed the next time the connection is used, or when returned to a
PgPool
in the case of PoolConnection<Postgres>
.
Postgres allows a single connection to acquire a given lock more than once without releasing it first, so in that sense the lock is re-entrant. However, the number of unlock operations must match the number of lock operations for the lock to actually be released.
See Postgres’ documentation for the Advisory Lock Functions for details.
sourcepub async fn try_acquire<C: AsMut<PgConnection>>(
&self,
conn: C
) -> Result<Either<PgAdvisoryLockGuard<'_, C>, C>>
pub async fn try_acquire<C: AsMut<PgConnection>>( &self, conn: C ) -> Result<Either<PgAdvisoryLockGuard<'_, C>, C>>
Acquires an exclusive lock using pg_try_advisory_lock()
, returning immediately
if the lock could not be acquired.
For a version that waits until the lock is acquired, see Self::acquire()
.
A connection-like type is required to execute the call. Allowed types include PgConnection
,
PoolConnection<Postgres>
and Transaction<Postgres>
, as well as mutable references to
any of these. The connection is returned if the lock could not be acquired.
The returned guard queues a pg_advisory_unlock()
call on the connection when dropped,
which will be executed the next time the connection is used, or when returned to a
PgPool
in the case of PoolConnection<Postgres>
.
Postgres allows a single connection to acquire a given lock more than once without releasing it first, so in that sense the lock is re-entrant. However, the number of unlock operations must match the number of lock operations for the lock to actually be released.
See Postgres’ documentation for the Advisory Lock Functions for details.
sourcepub async fn force_release<C: AsMut<PgConnection>>(
&self,
conn: C
) -> Result<(C, bool)>
pub async fn force_release<C: AsMut<PgConnection>>( &self, conn: C ) -> Result<(C, bool)>
Execute pg_advisory_unlock()
for this lock’s key on the given connection.
This is used by PgAdvisoryLockGuard::release_now()
and is also provided for manually
releasing the lock from connections returned by PgAdvisoryLockGuard::leak()
.
An error should only be returned if there is something wrong with the connection, in which case the lock will be automatically released by the connection closing anyway.
The boolean
value is that returned by pg_advisory_lock()
. If it is false
, it
indicates that the lock was not actually held by the given connection and that a warning
has been logged by the Postgres server.
Trait Implementations§
source§impl Clone for PgAdvisoryLock
impl Clone for PgAdvisoryLock
source§fn clone(&self) -> PgAdvisoryLock
fn clone(&self) -> PgAdvisoryLock
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read more