Skip to content

Commit 47a39f5

Browse files
author
James William Pye
committed
Relocate alock and notifyman into their own documents.
1 parent c1cb060 commit 47a39f5

6 files changed

Lines changed: 304 additions & 291 deletions

File tree

postgresql/documentation/alock.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
##
2+
# .documentation.alock
3+
##
4+
__doc__ = open(__file__[:__file__.rfind('.')] + '.txt').read()
5+
__docformat__ = 'reStructuredText'
6+
if __name__ == '__main__':
7+
help(__name__)

postgresql/documentation/alock.txt

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

0 commit comments

Comments
 (0)