mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-15 08:20:16 +08:00
3a694bb0a1
Essentially, we shoehorn in a lockable-object-type field by taking a byte away from the lockmethodid, which can surely fit in one byte instead of two. This allows less artificial definitions of all the other fields of LOCKTAG; we can get rid of the special pg_xactlock pseudo-relation, and also support locks on individual tuples and general database objects (including shared objects). None of those possibilities are actually exploited just yet, however. I removed pg_xactlock from pg_class, but did not force initdb for that change. At this point, relkind 's' (SPECIAL) is unused and could be removed entirely.
57 lines
2.6 KiB
Plaintext
57 lines
2.6 KiB
Plaintext
User locks, by Massimo Dal Zotto <dz@cs.unitn.it>
|
|
Copyright (C) 1999, Massimo Dal Zotto <dz@cs.unitn.it>
|
|
|
|
This software is distributed under the GNU General Public License
|
|
either version 2, or (at your option) any later version.
|
|
|
|
|
|
This loadable module provides support for user-level long-term cooperative
|
|
locks. For example one can write:
|
|
|
|
select some_fields, user_write_lock_oid(oid) from table where id='key';
|
|
|
|
Now if the returned user_write_lock_oid field is 1 you have acquired an
|
|
user lock on the oid of the selected tuple and can now do some long operation
|
|
on it, like let the data being edited by the user.
|
|
If it is 0 it means that the lock has been already acquired by some other
|
|
process and you should not use that item until the other has finished.
|
|
Note that in this case the query returns 0 immediately without waiting on
|
|
the lock. This is good if the lock is held for long time.
|
|
After you have finished your work on that item you can do:
|
|
|
|
update table set some_fields where id='key';
|
|
select user_write_unlock_oid(oid) from table where id='key';
|
|
|
|
You can also ignore the failure and go ahead but this could produce conflicts
|
|
or inconsistent data in your application. User locks require a cooperative
|
|
behavior between users. User locks don't interfere with the normal locks
|
|
used by Postgres for transaction processing.
|
|
|
|
This could also be done by setting a flag in the record itself but in
|
|
this case you have the overhead of the updates to the records and there
|
|
could be some locks not released if the backend or the application crashes
|
|
before resetting the lock flag.
|
|
It could also be done with a begin/end block but in this case the entire
|
|
table would be locked by Postgres and it is not acceptable to do this for
|
|
a long period because other transactions would block completely.
|
|
|
|
The generic user locks use two values, group and id, to identify a lock.
|
|
Each of these are 32-bit integers.
|
|
|
|
The oid user lock functions, which take only an OID as argument, store the
|
|
OID as "id" with a group equal to 0.
|
|
|
|
The meaning of group and id is defined by the application. The user
|
|
lock code just takes two numbers and tells you if the corresponding
|
|
entity has been successfully locked. What this means is up to you.
|
|
|
|
My suggestion is that you use the group to identify an area of your
|
|
application and the id to identify an object in this area.
|
|
|
|
In all cases, user locks are local to individual databases within an
|
|
installation.
|
|
|
|
Note also that a process can acquire more than one lock on the same entity
|
|
and it must release the lock the corresponding number of times. This can
|
|
be done by calling the unlock function until it returns 0.
|