Thread: Lifespan of a BeginInternalSubTransaction subxact ?

Lifespan of a BeginInternalSubTransaction subxact ?

From
Chapman Flack
Date:
Hi,

PL/Java implements JDBC Savepoints using BeginInternalSubTransaction/
ReleaseCurrentSubTransaction/RollbackAndReleaseCurrentSubTransaction.

That seems to be the Accepted Way of Doing Things within backend PLs
that want control over error recovery, am I right?

PL/Java also strictly enforces that such a subxact set within a Java
function must be released or rolled back by the time that function
returns.

The reasoning there is less obvious to me; my intuition would have been
that a subtransaction could remain in play for the life of its containing
transaction, which could have been started outside of this Java function;
by holding a reference to the JDBC Savepoint object, a later Java function
called in the same transaction could release it or roll it back.

But I am beginning to suspect that the limitation may be essential, given
the comments in xact.c around StartSubTransaction and how its effects would
get clobbered on exit from a Portal, so a subxact started by an actual
SAVEPOINT is started in two steps, the later one after the Portal has
exited. By contrast, within a function (being executed inside a Portal?),
I have to use BeginInternalSubTransaction, which combines the multiple steps
into one, but whose effects wouldn't survive the exit of the Portal.

Have I reverse-engineered this reasoning correctly? If so, I'll add some
comments about it in the PL/Java code where somebody may be thankful for
them later.

Or, if it turns out the limitation isn't so inescapable, and could be
relaxed to allow a subxact lifetime longer than the single function that
starts it, I could look into doing that.

Thanks!
-Chap


Re: Lifespan of a BeginInternalSubTransaction subxact ?

From
Tom Lane
Date:
Chapman Flack <chap@anastigmatix.net> writes:
> PL/Java implements JDBC Savepoints using BeginInternalSubTransaction/
> ReleaseCurrentSubTransaction/RollbackAndReleaseCurrentSubTransaction.
> That seems to be the Accepted Way of Doing Things within backend PLs
> that want control over error recovery, am I right?

Sounds about right, though I haven't checked the details exactly.

> PL/Java also strictly enforces that such a subxact set within a Java
> function must be released or rolled back by the time that function
> returns.

Yup.

> The reasoning there is less obvious to me; my intuition would have been
> that a subtransaction could remain in play for the life of its containing
> transaction, which could have been started outside of this Java function;

When control returns from a function, we resume executing the statement
that called it.  This can *not* be in a different (sub)transaction than
the statement started in; that wouldn't make any sense logically, and
it certainly won't work from an implementation standpoint either.

The rules are laxer for procedures, I believe; at the very least those are
allowed to commit the calling transaction and start a new one.  I'm less
sure about how they can interact with subtransactions.  To support this,
a CALL statement has to not have any internal state that persists past
the procedure call.  But a function cannot expect that the calling
statement lacks internal state.

            regards, tom lane