/usr/share/doc/python3-postgresql/html/_sources/alock.txt is in python3-postgresql 1.1.0-1build1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | .. _alock:
**************
Advisory Locks
**************
.. warning:: `postgresql.alock` is a new feature in v1.0.
`Explicit Locking in PostgreSQL <http://www.postgresql.org/docs/current/static/explicit-locking.html#ADVISORY-LOCKS>`_.
PostgreSQL's advisory locks offer a cooperative synchronization primitive.
These are used in cases where an application needs access to a resource, but
using table locks may cause interference with other operations that can be
safely performed alongside the application-level, exclusive operation.
Advisory locks can be used by directly executing the stored procedures in the
database or by using the :class:`postgresql.alock.ALock` subclasses, which
provides a context manager that uses those stored procedures.
Currently, only two subclasses exist. Each represents the lock mode
supported by PostgreSQL's advisory locks:
* :class:`postgresql.alock.ShareLock`
* :class:`postgresql.alock.ExclusiveLock`
Acquiring ALocks
================
An ALock instance represents a sequence of advisory locks. A single ALock can
acquire and release multiple advisory locks by creating the instance with
multiple lock identifiers::
>>> from postgresql import alock
>>> table1_oid = 192842
>>> table2_oid = 192849
>>> l = alock.ExclusiveLock(db, (table1_oid, 0), (table2_oid, 0))
>>> l.acquire()
>>> ...
>>> l.release()
:class:`postgresql.alock.ALock` is similar to :class:`threading.RLock`; in
order for an ALock to be released, it must be released the number of times it
has been acquired. ALocks are associated with and survived by their session.
Much like how RLocks are associated with the thread they are acquired in:
acquiring an ALock again will merely increment its count.
PostgreSQL allows advisory locks to be identified using a pair of `int4` or a
single `int8`. ALock instances represent a *sequence* of those identifiers::
>>> from postgresql import alock
>>> ids = [(0,0), 0, 1]
>>> with alock.ShareLock(db, *ids):
... ...
Both types of identifiers may be used within the same ALock, and, regardless of
their type, will be aquired in the order that they were given to the class'
constructor. In the above example, ``(0,0)`` is acquired first, then ``0``, and
lastly ``1``.
ALocks
======
`postgresql.alock.ALock` is abstract; it defines the interface and some common
functionality. The lock mode is selected by choosing the appropriate subclass.
There are two:
``postgresql.alock.ExclusiveLock(database, *identifiers)``
Instantiate an ALock object representing the `identifiers` for use with the
`database`. Exclusive locks will conflict with other exclusive locks and share
locks.
``postgresql.alock.ShareLock(database, *identifiers)``
Instantiate an ALock object representing the `identifiers` for use with the
`database`. Share locks can be acquired when a share lock with the same
identifier has been acquired by another backend. However, an exclusive lock
with the same identifier will conflict.
ALock Interface Points
----------------------
Methods and properties available on :class:`postgresql.alock.ALock` instances:
``alock.acquire(blocking = True)``
Acquire the advisory locks represented by the ``alock`` object. If blocking is
`True`, the default, the method will block until locks on *all* the
identifiers have been acquired.
If blocking is `False`, acquisition may not block, and success will be
indicated by the returned object: `True` if *all* lock identifiers were
acquired and `False` if any of the lock identifiers could not be acquired.
``alock.release()``
Release the advisory locks represented by the ``alock`` object. If the lock
has not been acquired, a `RuntimeError` will be raised.
``alock.locked()``
Returns a boolean describing whether the locks are held or not. This will
return `False` if the lock connection has been closed.
``alock.__enter__()``
Alias to ``acquire``; context manager protocol. Always blocking.
``alock.__exit__(typ, val, tb)``
Alias to ``release``; context manager protocol.
|