I wrote:
> Robert Haas <robertmhaas@gmail.com> writes:
>> In fact I'm a bit confused by the original complaint for the same
>> reason - if LockRelationOid and LockRelationIdForSession can coexist,
>> why doesn't the same thing work for advisory locks?
> The problem (or problems) is bad implementation, not the specification.
> In particular, at least one place that should have been patched was not.
After calming down a bit and reading the patch more, I think the only
place that was really seriously overlooked was PREPARE TRANSACTION,
specifically AtPrepare_Locks/PostPrepare_Locks. To some extent this is
just a matter of missing code, but there is one assumption in there that
seems hard to get around: the code expects that any given lock object
will be held at session level or at transaction level, never both.
If it is held at session level then ownership stays with the current
session, otherwise ownership of the lock is transferred to the prepared
transaction (the gxact object). Since advisory-lock objects can be held
at session and transaction levels concurrently, this assumption fails.
It might seem obvious to move the transaction lock to the prepared xact
while keeping the session ownership, but that doesn't look workable
because it would require an additional ProcLock object in shared memory,
which we cannot guarantee in advance is available (and failing at the
PostPrepare stage is not acceptable).
I'm inclined to say that you can PREPARE if your session holds a given
advisory lock at either session or transaction level, but not both.
This is a bit annoying but doesn't seem likely to be a real problem in
practice, so thinking of a hack to support the case seems like more
work than is justified.
regards, tom lane