sqlalchemy_dlock.lock.postgresql module#

class sqlalchemy_dlock.lock.postgresql.PostgresqlSadLockMixin(*, key, shared: bool = False, xact: bool = False, convert: Callable[[Any], int] | None = None, **kwargs)#

Bases: object

A Mix-in class for PostgreSQL advisory lock

Parameters:
  • key

    PostgreSQL advisory lock requires the key given by INT64.

    • When key is int, the constructor tries to ensure it to be INT64. OverflowError is raised if too big or too small for that.

    • When key is str or bytes or alike, the constructor calculates its checksum by hashlib.blake2b(), and takes the hash result integer value as actual key.

    • Or you can specify a convert function to that argument:

      def convert(val: Any) -> int:
          int64_key: int = do_sth(val)
          return int64_key
      

  • shared (bool) – shared

  • xact (bool) – xact

  • convert (Callable[[Any], int] | None) – Custom function to covert key to required data type.

property actual_key: int#
property shared: bool#

Is the advisory lock shared or exclusive

property xact: bool#

Is the advisory lock transaction level or session level

class sqlalchemy_dlock.lock.postgresql.PostgresqlSadLock(connection_or_session: TConnectionOrSession, key, **kwargs)#

Bases: PostgresqlSadLockMixin, BaseSadLock

A distributed lock implemented by PostgreSQL advisory lock

Tip

Locks can be either shared or exclusive: a shared lock does not conflict with other shared locks on the same resource, only with exclusive locks. Locks can be taken at session level (so that they are held until released or the session ends) or at transaction level (so that they are held until the current transaction ends; there is no provision for manual release). Multiple session-level lock requests stack, so that if the same resource identifier is locked three times there must then be three unlock requests to release the resource in advance of session end.

Parameters:
acquire(block: bool = True, timeout: float | int | None = None, interval: float | int | None = None) bool#

Attention

PostgreSQL’s advisory lock has no timeout mechanism in itself. When timeout is a non-negative number, we simulate it by looping and sleeping.

The interval argument specifies the sleep seconds(1 by default).

That is:

The actual timeout won’t be precise when interval is big; while small interval will cause high CPU usage and frequent SQL execution.

Parameters:
Return type:

bool

release()#

Release a lock.

Since the class is thread-local, this cannot be called from other thread or process, and also can not be called from other connection. (Although PostgreSQL’s shared advisory lock supports so).

When the lock is locked, reset it to unlocked, and return. If any other threads are blocked waiting for the lock to become unlocked, allow exactly one of them to proceed.

When invoked on an unlocked lock, a ValueError is raised.

There is no return value.