sqlalchemy_dlock.impl.postgresql module

class sqlalchemy_dlock.impl.postgresql.SessionLevelLock(connection_or_session: Union[sqlalchemy.engine.base.Connection, sqlalchemy.orm.session.Session, sqlalchemy.orm.scoping.scoped_session], key, *, convert: Optional[Callable[[Any], int]] = None, interval: Optional[Union[float, int]] = None, level: Optional[str] = None, **_)

Bases: sqlalchemy_dlock.sessionlevellock.AbstractSessionLevelLock

PostgreSQL advisory lock

PostgreSQL advisory lock requires the key given by INT64.

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

  • When key is str or bytes, the constructor calculates its checksum using CRC-64(ISO), and takes the checksum integer value as actual key.

  • Or you can specify a convert function to that argument. The function is like:

    def convert(val: Any) -> int:
        # do something ...
        return integer
    

The level argument should be one of:

  • "session" (Omitted): locks an application-defined resource.

    If another session already holds a lock on the same resource identifier, this function will wait until the resource becomes available. The lock is exclusive. Multiple lock requests stack, so that if the same resource is locked three times it must then be unlocked three times to be released for other sessions’ use.

  • "shared": works the same as session level lock, except the lock can be shared with other sessions requesting shared locks.

    Only would-be exclusive lockers are locked out.

  • "transaction": works the same as session level lock, except the lock is automatically released at the end of the current transaction and cannot be released explicitly.

Tip

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, whose default is 1.

acquire(block: bool = True, timeout: Optional[Union[float, int]] = None, *, interval: Optional[Union[float, int]] = None, **_) bool

Acquire a lock, blocking or non-blocking.

  • With the block argument set to True (the default), the method call will block until the lock is in an unlocked state, then set it to locked and return True.

  • With the block argument set to False, the method call does not block. If the lock is currently in a locked state, return False; otherwise set the lock to a locked state and return True.

  • When invoked with a positive, floating-point value for timeout, block for at most the number of seconds specified by timeout as long as the lock can not be acquired. Invocations with a negative value for timeout are equivalent to a timeout of zero. Invocations with a timeout value of None (the default) set the timeout period to infinite. The timeout argument has no practical implications if the block argument is set to False and is thus ignored. Returns True if the lock has been acquired or False if the timeout period has elapsed.

property level: str
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 (PostgreSQL’s shared advisory lock supports so, but we haven’t).

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.

sqlalchemy_dlock.impl.postgresql.default_convert(key: Union[bytearray, bytes, memoryview, str, int]) int
sqlalchemy_dlock.impl.postgresql.ensure_int64(i: int) int