Thread: Timing of notice delivery

Timing of notice delivery

From
"Kevin Grittner"
Date:
In 9.0.3 with postgresql-9.0-801.jdbc4.jar (if version matters), I'm
wondering whether a single connection which has a listener
registered, and within a transaction generates notifications, can
commit and immediately request notifications with assurance that all
notifications generated before the commit will be delivered on that
first getNotifications() invocation after the commit.

In other words, all on one thread, all on one connection:

-- setup
Execute LISTEN on the connection.
conn.setAutoCommit(false);
-- each transaction
execute statements which fire triggers which NOTIFY.
conn.commit();
conn.getNotifications();

Can I count on all notifications triggered during a transaction
being delivered in the last step?

If not, does running one dummy query, committing, and invoking
getNotifications() again ensure that I have them all?

If not, is there any way to determine when all notifications from
that transaction have been delivered?

Remember: all on one thread, all on one connection.

-Kevin

Re: Timing of notice delivery

From
Tom Lane
Date:
"Kevin Grittner" <Kevin.Grittner@wicourts.gov> writes:
> In other words, all on one thread, all on one connection:

> -- setup
> Execute LISTEN on the connection.
> conn.setAutoCommit(false);
> -- each transaction
> execute statements which fire triggers which NOTIFY.
> conn.commit();
> conn.getNotifications();

> Can I count on all notifications triggered during a transaction
> being delivered in the last step?

The backend will deliver all such notifies after returning the COMMIT's
command-complete response message, but before it delivers ReadyForQuery.
If JDBC waits for ReadyForQuery before believing the operation is
complete, you should see them reliably.

I believe that the situation for incoming notifies from other sessions
is a bit less predictable, though --- it looks like those can get sent
*after* ReadyForQuery, even if they arrived beforehand.

            regards, tom lane

Re: Timing of notice delivery

From
Oliver Jowett
Date:
On 02/02/11 12:51, Kevin Grittner wrote:

> -- setup
> Execute LISTEN on the connection.
> conn.setAutoCommit(false);
> -- each transaction
> execute statements which fire triggers which NOTIFY.
> conn.commit();
> conn.getNotifications();
>
> Can I count on all notifications triggered during a transaction
> being delivered in the last step?

This is equivalent to asking "Does the server deliver all notifications
before sending ReadyForQuery in response to Sync after the commit
command?". The last thing the driver processes from the server before
returning from commit() is the RFQ message.

Oliver

Re: Timing of notice delivery

From
"Kevin Grittner"
Date:
Oliver Jowett  wrote:

> This is equivalent to asking "Does the server deliver all
> notifications before sending ReadyForQuery in response to Sync
> after the commit command?". The last thing the driver processes
> from the server before returning from commit() is the RFQ message.

Tom Lane  wrote:

> The backend will deliver all such notifies after returning the
> COMMIT's command-complete response message, but before it delivers
> ReadyForQuery.  If JDBC waits for ReadyForQuery before believing
> the operation is complete, you should see them reliably.

Good news!  Many thanks to both of you!

> I believe that the situation for incoming notifies from other
> sessions is a bit less predictable, though --- it looks like those
> can get sent *after* ReadyForQuery, even if they arrived
> beforehand.

Thanks, I'll keep that in mind.  The immediate issue was regarding
self-notification; knowing we can rely on that keep things simple for
us there.  I would expect inter-session messaging to be less
deterministic.  I'm sure we can make that work as long as we don't
make the wrong assumptions.

-Kevin

Re: Timing of notice delivery

From
"Donald Fraser"
Date:
Kevin Grittner wrote:

> Thanks, I'll keep that in mind.  The immediate issue was regarding
> self-notification; knowing we can rely on that keep things simple for

When you mean "self-notification" I assume you mean notifications via
transactions from your connection?
If its an identification issue, you can always work out which notifications
are "self-notifications" via the PID, which is part of the notification
message. You can easily find your connection's PID immediately after
connecting (SELECT pg_backend_pid()).

Regards
Donald Fraser


Re: Timing of notice delivery

From
"Kevin Grittner"
Date:
"Donald Fraser" <postgres@kiwi-fraser.net> wrote:

> If its an identification issue, you can always work out which
> notifications are "self-notifications" via the PID

No, it's strictly a timing issue.  Can the JDBC client which has
just committed a transaction count on getNotifications returning all
relevant notifications from that transaction?  The answer is yes,
which is convenient for us.  The use case is that we will have
triggers firing at the PostgreSQL level, and we don't want the
application to have to be aware of what triggers are there or to
make any assumptions about what these triggers will do; but we want
the JDBC client to be notified about what they actually *did* -- so
that GUI components reflecting the data modified by the triggers can
be updated.

Of course, ultimately we would like to get to a point where all
users displaying relevant data are updated quickly and
automatically, but there are performance considerations to that
which haven't been worked out entirely.  Right now we just want to
make sure that the user making the base change gets immediate
feedback on all side-effects.  This has already been happening
through a Java tier just above the database, but we've decided to
commit to PostgreSQL rather than maintaining database independence,
which allows us to push some of this down to the database level.
We're just trying to work out how to maintain existing functionality
during the switchover, which we've decided to do incrementally, over
the course of a few years -- although this first step of converting
the triggers and stored procedures to PostgreSQL triggers and
functions needs to be done in a single application update before we
do much else.

Ultimately, this will save us from having to maintain a lot of
home-grown infrastructure.  We currently write all our triggers and
stored procedures in an ANSI-SQL-based format, parse that and
generate Java classes to implement the triggers and stored
procedures in that intermediate level.  Even if we need to patch
PostgreSQL here and there, the work should be pretty minimal
compared to what we do now.  Fortunately , it's been pretty
reasonable to create a tree-walker for the tree emitted from our
current parser which emits PostgreSQL functions and triggers.  :-)

But I digress...  Thanks for the suggestion, anyway.

-Kevin