what happens if a failed transaction is not rolled back?

Started by Siddharth Jainalmost 3 years ago11 messagesgeneral
Jump to latest
#1Siddharth Jain
siddhsql@gmail.com

Hi All,

i understand when writing application code, we should rollback a
transaction that fails to commit. this is typically done in the catch block
of a try-catch exception handler. but what if the developer does not
rollback the transaction? what happens in that case?

note that i am not asking: what happens if a transaction is not rolled back?
i am asking: what happens if a *failed* transaction is not rolled back?

failed transaction = you try to commit it but get an exception back from
the database.

thanks.

S.

#2Adrian Klaver
adrian.klaver@aklaver.com
In reply to: Siddharth Jain (#1)
Re: what happens if a failed transaction is not rolled back?

On 4/24/23 08:37, Siddharth Jain wrote:

Hi All,

i understand when writing application code, we should rollback a
transaction that fails to commit. this is typically done in the catch
block of a try-catch exception handler. but what if the developer does
not rollback the transaction? what happens in that case?

note that i am not asking: what happens if a transaction is not rolled back?
i am asking: what happens if a /failed/ transaction is not rolled back?

failed transaction = you try to commit it but get an exception back from
the database.

In Python:

import psycopg2
con = psycopg2.connect("dbname=test host=localhost user=postgres")
cur = con.cursor()
cur.execute("select 1/0")
DivisionByZero: division by zero

cur.execute("select 1")
InFailedSqlTransaction: current transaction is aborted, commands ignored
until end of transaction block

thanks.

S.

--
Adrian Klaver
adrian.klaver@aklaver.com

#3Adrian Klaver
adrian.klaver@aklaver.com
In reply to: Adrian Klaver (#2)
Re: what happens if a failed transaction is not rolled back?

On 4/24/23 08:43, Adrian Klaver wrote:

On 4/24/23 08:37, Siddharth Jain wrote:

Hi All,

i understand when writing application code, we should rollback a
transaction that fails to commit. this is typically done in the catch
block of a try-catch exception handler. but what if the developer does
not rollback the transaction? what happens in that case?

note that i am not asking: what happens if a transaction is not rolled
back?
i am asking: what happens if a /failed/ transaction is not rolled back?

failed transaction = you try to commit it but get an exception back
from the database.

In Python:

import psycopg2
con = psycopg2.connect("dbname=test host=localhost  user=postgres")
cur = con.cursor()
cur.execute("select 1/0")
DivisionByZero: division by zero

cur.execute("select 1")
InFailedSqlTransaction: current transaction is aborted, commands ignored
until end of transaction block

Forgot to add.

To get past above:

con.rollback()
cur.execute("select 1")

thanks.

S.

--
Adrian Klaver
adrian.klaver@aklaver.com

#4David G. Johnston
david.g.johnston@gmail.com
In reply to: Siddharth Jain (#1)
Re: what happens if a failed transaction is not rolled back?

On Mon, Apr 24, 2023 at 8:37 AM Siddharth Jain <siddhsql@gmail.com> wrote:

Hi All,

i understand when writing application code, we should rollback a
transaction that fails to commit. this is typically done in the catch block
of a try-catch exception handler. but what if the developer does not
rollback the transaction? what happens in that case?

note that i am not asking: what happens if a transaction is not rolled
back?
i am asking: what happens if a *failed* transaction is not rolled back?

failed transaction = you try to commit it but get an exception back from
the database.

There isn't anything special about a failed transaction compared to any
other transaction that you leave open.

Might help to describe what the application does with the connection
subsequent to the point of attempted commit.

David J.

#5Luca Ferrari
fluca1978@gmail.com
In reply to: Siddharth Jain (#1)
Re: what happens if a failed transaction is not rolled back?

On Mon, Apr 24, 2023 at 5:37 PM Siddharth Jain <siddhsql@gmail.com> wrote:

i am asking: what happens if a failed transaction is not rolled back?

A transaction either terminates by a commit or by a rollback. A failed
transaction is an opened transaction that can be terminated only by a
rollback.
If you don't rollback, then your transaction is hold by the driver,
that means for instance your pooler is not able to recycle it.
Clearly, the exact behavior depends by the driver.

#6David Wheeler
hippysoyboy@gmail.com
In reply to: David G. Johnston (#4)
Re: what happens if a failed transaction is not rolled back?

On 25 Apr 2023, at 1:47 am, David G. Johnston <david.g.johnston@gmail.com> wrote:

There isn't anything special about a failed transaction compared to any other transaction that you leave open.

Now I’m curious. Does it have the same impact on performance that an idle in transaction connection has? Eg does it prevent vacuum? Does it still hold locks?

David

#7David G. Johnston
david.g.johnston@gmail.com
In reply to: David Wheeler (#6)
Re: what happens if a failed transaction is not rolled back?

On Mon, Apr 24, 2023 at 12:56 PM David Wheeler <hippysoyboy@gmail.com>
wrote:

On 25 Apr 2023, at 1:47 am, David G. Johnston <david.g.johnston@gmail.com>
wrote:

There isn't anything special about a failed transaction compared to any
other transaction that you leave open.

Now I’m curious. Does it have the same impact on performance that an idle
in transaction connection has? Eg does it prevent vacuum? Does it still
hold locks?

Absent documentation to the contrary I would expect the system to at best
be in an idle-in-transaction state as-if the failed command never was
executed. The concept of savepoints, whether in use in a particular
transaction, would require at least that much state be preserved.

David J.

#8Tom Lane
tgl@sss.pgh.pa.us
In reply to: David G. Johnston (#7)
Re: what happens if a failed transaction is not rolled back?

"David G. Johnston" <david.g.johnston@gmail.com> writes:

On Mon, Apr 24, 2023 at 12:56 PM David Wheeler <hippysoyboy@gmail.com>
wrote:

Now I’m curious. Does it have the same impact on performance that an idle
in transaction connection has? Eg does it prevent vacuum? Does it still
hold locks?

Absent documentation to the contrary I would expect the system to at best
be in an idle-in-transaction state as-if the failed command never was
executed.

A quick experiment will show you that we release locks as soon as the
transaction is detected to have failed. I believe the same is true of
other interesting resources such as snapshots (which'd be what affects
vacuum) but it's less easy to observe that from the SQL level. At least
by intention, a failed transaction won't hold any resources that would
impact other sessions.

The concept of savepoints, whether in use in a particular
transaction, would require at least that much state be preserved.

Of course, we can't release resources that were acquired by a still-live
subtransaction, a/k/a savepoint.

regards, tom lane

#9Merlin Moncure
mmoncure@gmail.com
In reply to: Tom Lane (#8)
Re: what happens if a failed transaction is not rolled back?

On Mon, Apr 24, 2023 at 4:20 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:

"David G. Johnston" <david.g.johnston@gmail.com> writes:

On Mon, Apr 24, 2023 at 12:56 PM David Wheeler <hippysoyboy@gmail.com>
wrote:

Now I’m curious. Does it have the same impact on performance that an

idle

in transaction connection has? Eg does it prevent vacuum? Does it still
hold locks?

Absent documentation to the contrary I would expect the system to at best
be in an idle-in-transaction state as-if the failed command never was
executed.

A quick experiment will show you that we release locks as soon as the
transaction is detected to have failed. I believe the same is true of
other interesting resources such as snapshots (which'd be what affects
vacuum) but it's less easy to observe that from the SQL level. At least
by intention, a failed transaction won't hold any resources that would
impact other sessions.

The concept of savepoints, whether in use in a particular
transaction, would require at least that much state be preserved.

Of course, we can't release resources that were acquired by a still-live
subtransaction, a/k/a savepoint.

I think testing pg_stat_activity.backend_xid being not null does the trick.
If it's null, it either never took an xid by doing something that is worth
having one assigned after transaction start (including immediately after
procedure commit;), or had one that was released when aborted (if there is
an active savepoint it would keep backend_xid not null). Of course, you
can't do that from the aborted transaction until it's rolled back first.

Hm. I also noticed when looking at this that aborted transactions with
savepoints are not subjected to the idle_in_transaction timeout which is a
bit surprising.
.

merlin

#10Tom Lane
tgl@sss.pgh.pa.us
In reply to: Merlin Moncure (#9)
Re: what happens if a failed transaction is not rolled back?

Merlin Moncure <mmoncure@gmail.com> writes:

Hm. I also noticed when looking at this that aborted transactions with
savepoints are not subjected to the idle_in_transaction timeout which is a
bit surprising.

Hmm ... I think it's intentional that idle_in_transaction no longer
applies once the transaction has failed. But if there's a live
savepoint, then we should enforce it since resources may still be
held. Seems like a bug, if your observation is accurate.

regards, tom lane

#11Merlin Moncure
mmoncure@gmail.com
In reply to: Tom Lane (#10)
Re: what happens if a failed transaction is not rolled back?

On Mon, Apr 24, 2023 at 8:41 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:

Merlin Moncure <mmoncure@gmail.com> writes:

Hm. I also noticed when looking at this that aborted transactions with
savepoints are not subjected to the idle_in_transaction timeout which is

a

bit surprising.

Hmm ... I think it's intentional that idle_in_transaction no longer
applies once the transaction has failed. But if there's a live
savepoint, then we should enforce it since resources may still be
held. Seems like a bug, if your observation is accurate.

hm, double checking, it's not.

merlin