Implicit transaction not rolling back after error

Started by Stephen Tousetover 13 years ago7 messagesgeneral
Jump to latest
#1Stephen Touset
stephen.touset+postgresql@onelogin.com

I'm having difficulty locating the source of a problem our webapp has
been running into. Multiple Google searches have failed me, so I'm
hoping someone here can help troubleshoot.

When some clients (psql, the webapp) connect to our production
database, they become stuck in an aborted transaction after any failed
statement. For example:

$ psql --version
psql (PostgreSQL) 9.0.5
$ psql test
psql (9.0.5)
SSL connection (cipher: DHE-RSA-AES256-SHA, bits: 256)
Type "help" for help.

test=> SELECT foo;
ERROR: column "foo" does not exist
LINE 1: SELECT foo;
^
test=> SELECT VERSION();
ERROR: current transaction is aborted, commands ignored until end
of transaction block

Of course, there is no explicit transaction around the first
statement, but no commands can be issued until after a ROLLBACK.

Stangely, I don't encounter this issue if I connect directly from my
development machine.

$ psql --version
psql (PostgreSQL) 9.2.1
$ psql --host $HOST test
psql (9.2.1, server 9.0.5)
WARNING: psql version 9.2, server version 9.0.
Some psql features might not work.
SSL connection (cipher: DHE-RSA-AES256-SHA, bits: 256)
Type "help" for help.

test=> SELECT foo;
ERROR: column "foo" does not exist
LINE 1: SELECT foo;
^
test=> SELECT VERSION();
version
-------------------------------------------------------------------------------------------------------------
PostgreSQL 9.0.5 on x86_64-pc-linux-gnu, compiled by GCC
gcc-4.4.real (Ubuntu 4.4.3-4ubuntu5) 4.4.3, 64-bit
(1 row)

I also don't encounter the issue if I connect to the running 9.2
daemon on my development machine either.

Our production webapp also suffers from this problem (which is how we
noticed it in the first place). It connects to the PostgreSQL daemon
through a Ruby library (pg) which wraps libpq5. I assumed the only
commonality between psql and our application was libpq5, so upgraded
it to a later version (9.2.2) with no luck.

Does anyone know what this might be? Is it a bug? A feature? A
configuration issue? I'm kind of at a loss at this point.

Thanks in advance for your help.

--
Stephen Touset
Senior Software Engineer
stephen.touset@onelogin.com

--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general

#2Adrian Klaver
adrian.klaver@aklaver.com
In reply to: Stephen Touset (#1)
Re: Implicit transaction not rolling back after error

On 12/20/2012 03:11 PM, Stephen Touset wrote:

I'm having difficulty locating the source of a problem our webapp has
been running into. Multiple Google searches have failed me, so I'm
hoping someone here can help troubleshoot.

I also don't encounter the issue if I connect to the running 9.2
daemon on my development machine either.

Our production webapp also suffers from this problem (which is how we
noticed it in the first place). It connects to the PostgreSQL daemon
through a Ruby library (pg) which wraps libpq5. I assumed the only
commonality between psql and our application was libpq5, so upgraded
it to a later version (9.2.2) with no luck.

Does anyone know what this might be? Is it a bug? A feature? A
configuration issue? I'm kind of at a loss at this point.

Well for the psql case check out:

http://www.postgresql.org/docs/9.0/interactive/app-psql.html

"
AUTOCOMMIT
When on (the default), each SQL command is automatically committed upon
successful completion. To postpone commit in this mode, you must enter a
BEGIN or START TRANSACTION SQL command. When off or unset, SQL commands
are not committed until you explicitly issue COMMIT or END. The
autocommit-off mode works by issuing an implicit BEGIN for you, just
before any command that is not already in a transaction block and is not
itself a BEGIN or other transaction-control command, nor a command that
cannot be executed inside a transaction block (such as VACUUM).

Note: In autocommit-off mode, you must explicitly abandon any failed
transaction by entering ABORT or ROLLBACK. Also keep in mind that if you
exit the session without committing, your work will be lost.
Note: The autocommit-on mode is PostgreSQL's traditional behavior, but
autocommit-off is closer to the SQL spec. If you prefer autocommit-off,
you might wish to set it in the system-wide psqlrc file or your
~/.psqlrc file.

"

Not sure about the Ruby case.

Thanks in advance for your help.

--
Adrian Klaver
adrian.klaver@gmail.com

--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general

#3Stephen Touset
stephen.touset@onelogin.com
In reply to: Adrian Klaver (#2)
Re: Implicit transaction not rolling back after error

On Dec 20, 2012, at 3:27 PM, Adrian Klaver <adrian.klaver@gmail.com> wrote:

When on (the default), each SQL command is automatically committed upon successful completion. To postpone commit in this mode, you must enter a BEGIN or START TRANSACTION SQL command. When off or unset, SQL commands are not committed until you explicitly issue COMMIT or END. The autocommit-off mode works by issuing an implicit BEGIN for you, just before any command that is not already in a transaction block and is not itself a BEGIN or other transaction-control command, nor a command that cannot be executed inside a transaction block (such as VACUUM).

Note: In autocommit-off mode, you must explicitly abandon any failed transaction by entering ABORT or ROLLBACK. Also keep in mind that if you exit the session without committing, your work will be lost.
Note: The autocommit-on mode is PostgreSQL's traditional behavior, but autocommit-off is closer to the SQL spec. If you prefer autocommit-off, you might wish to set it in the system-wide psqlrc file or your ~/.psqlrc file.

In this case, not only is AUTOCOMMIT set to "on", but I wasn't even able to turn it off for testing purposes.

test=# SET AUTOCOMMIT TO off;
ERROR: SET AUTOCOMMIT TO OFF is no longer supported

So yes, AUTOCOMMIT is definitely on.

--
Stephen Touset
Senior Software Engineer
stephen.touset@onelogin.com

--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general

#4Stephen Touset
stephen.touset@onelogin.com
In reply to: Adrian Klaver (#2)
Re: Implicit transaction not rolling back after error

On Dec 20, 2012, at 3:27 PM, Adrian Klaver <adrian.klaver@gmail.com> wrote:

When on (the default), each SQL command is automatically committed upon successful completion. To postpone commit in this mode, you must enter a BEGIN or START TRANSACTION SQL command. When off or unset, SQL commands are not committed until you explicitly issue COMMIT or END. The autocommit-off mode works by issuing an implicit BEGIN for you, just before any command that is not already in a transaction block and is not itself a BEGIN or other transaction-control command, nor a command that cannot be executed inside a transaction block (such as VACUUM).

Note: In autocommit-off mode, you must explicitly abandon any failed transaction by entering ABORT or ROLLBACK. Also keep in mind that if you exit the session without committing, your work will be lost.
Note: The autocommit-on mode is PostgreSQL's traditional behavior, but autocommit-off is closer to the SQL spec. If you prefer autocommit-off, you might wish to set it in the system-wide psqlrc file or your ~/.psqlrc file.

Actually, you may be onto something.

test=> COMMIT;
WARNING: there is no transaction in progress
COMMIT
onelogin_production=> SHOW AUTOCOMMIT;
autocommit
------------
on
(1 row)

test=> COMMIT;
COMMIT

If I try to do a bare "COMMIT", I get a warning that there's no transaction in progress. But if I do a simple SHOW, and COMMIT afterward, I get no such warning (indicating that I'm still inside of an uncommitted transaction). However, obviously, the client is telling me explicitly in the provided log that AUTOCOMMIT is on.

--
Stephen Touset
Senior Software Engineer
stephen.touset@onelogin.com

--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general

#5Rob Sargent
robjsargent@gmail.com
In reply to: Stephen Touset (#3)
Re: Implicit transaction not rolling back after error

On 12/20/2012 04:33 PM, Stephen Touset wrote:

On Dec 20, 2012, at 3:27 PM, Adrian Klaver <adrian.klaver@gmail.com> wrote:

When on (the default), each SQL command is automatically committed upon successful completion. To postpone commit in this mode, you must enter a BEGIN or START TRANSACTION SQL command. When off or unset, SQL commands are not committed until you explicitly issue COMMIT or END. The autocommit-off mode works by issuing an implicit BEGIN for you, just before any command that is not already in a transaction block and is not itself a BEGIN or other transaction-control command, nor a command that cannot be executed inside a transaction block (such as VACUUM).

Note: In autocommit-off mode, you must explicitly abandon any failed transaction by entering ABORT or ROLLBACK. Also keep in mind that if you exit the session without committing, your work will be lost.
Note: The autocommit-on mode is PostgreSQL's traditional behavior, but autocommit-off is closer to the SQL spec. If you prefer autocommit-off, you might wish to set it in the system-wide psqlrc file or your ~/.psqlrc file.

In this case, not only is AUTOCOMMIT set to "on", but I wasn't even able to turn it off for testing purposes.

test=# SET AUTOCOMMIT TO off;
ERROR: SET AUTOCOMMIT TO OFF is no longer supported

So yes, AUTOCOMMIT is definitely on.

What does \set show when entered from the psql command line?

--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general

#6Stephen Touset
stephen.touset@onelogin.com
In reply to: Rob Sargent (#5)
Re: Implicit transaction not rolling back after error

On Dec 20, 2012, at 3:40 PM, Rob Sargent <robjsargent@gmail.com> wrote:

On 12/20/2012 04:33 PM, Stephen Touset wrote:

So yes, AUTOCOMMIT is definitely on.

What does \set show when entered from the psql command line?

test=> \set
AUTOCOMMIT = 'OFF'

*facepalm*.

Turns out someone put a .psqlrc with autocommit off in /etc/skel when the box was originally set up as a replacement for our previous app server. Account users were created afterwards, and the change propagated to our application account as well as all of our individual accounts.

Why, though, would `SHOW AUTOCOMMIT` lie? And `SET AUTOCOMMIT TO off` says that capability is disabled. So how does the config file manage to do it?

Thanks for the insight!

--
Stephen Touset
Senior Software Engineer
stephen.touset@onelogin.com

--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general

#7Scott Marlowe
scott.marlowe@gmail.com
In reply to: Stephen Touset (#6)
Re: Implicit transaction not rolling back after error

On Thu, Dec 20, 2012 at 7:04 PM, Stephen Touset
<stephen.touset@onelogin.com> wrote:

On Dec 20, 2012, at 3:40 PM, Rob Sargent <robjsargent@gmail.com> wrote:

On 12/20/2012 04:33 PM, Stephen Touset wrote:

So yes, AUTOCOMMIT is definitely on.

What does \set show when entered from the psql command line?

test=> \set
AUTOCOMMIT = 'OFF'

*facepalm*.

\set is a psql command

Turns out someone put a .psqlrc with autocommit off in /etc/skel when the box was originally set up as a replacement for our previous app server. Account users were created afterwards, and the change propagated to our application account as well as all of our individual accounts.

Why, though, would `SHOW AUTOCOMMIT` lie? And `SET AUTOCOMMIT TO off` says that capability is disabled. So how does the config file manage to do it?

show variable is a SQL command to the backend engine. The backend
does not support autocommit on / off (it did once upon a time for a
little while but it broke lots of stuff and got reverted).

autocommit is now firmly a client side behavior, not a backend behavior.

--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general