mirror of
https://github.com/psycopg/psycopg2.git
synced 2024-11-22 17:06:33 +03:00
Don't execute a ROLLBACK on close()/GC.
The command wasn't sent since 2.2.0 due to a bug, but after a ML discussion this behaviour proved more correct so the bug has become a feature.
This commit is contained in:
parent
cb1ef242a0
commit
2081ceffde
|
@ -1,3 +1,10 @@
|
|||
2010-08-05 Daniele Varrazzo <daniele.varrazzo@gmail.com>
|
||||
|
||||
* psycopg/connection_int.c: don't execute a ROLLBACK on close()/GC.
|
||||
The command wasn't sent since 2.2.0 due to a bug, but after a ML
|
||||
discussion this behaviour proved more correct so the bug has become a
|
||||
feature.
|
||||
|
||||
2010-07-18 Federico Di Gregorio <fog@initd.org>
|
||||
|
||||
* Release 2.2.2.
|
||||
|
|
|
@ -67,10 +67,28 @@ The ``connection`` class
|
|||
`~psycopg2.InterfaceError` will be raised if any operation is
|
||||
attempted with the connection. The same applies to all cursor objects
|
||||
trying to use the connection. Note that closing a connection without
|
||||
committing the changes first will cause an implicit rollback to be
|
||||
performed (unless a different isolation level has been selected: see
|
||||
committing the changes first will cause any pending change to be
|
||||
discarded as if a :sql:`ROLLBACK` was performed (unless a different
|
||||
isolation level has been selected: see
|
||||
`~connection.set_isolation_level()`).
|
||||
|
||||
.. index::
|
||||
single: PgBouncer; unclean server
|
||||
|
||||
.. versionchanged:: 2.2
|
||||
previously an explicit :sql:`ROLLBACK` was issued by Psycopg on
|
||||
`!close()`. The command could have been sent to the backend at an
|
||||
inappropriate time, so Psycopg currently relies on the backend to
|
||||
implicitly discard uncommitted changes. Some middleware are known
|
||||
to behave incorrectly though when the connection is closed during
|
||||
a transaction (when `~connection.status` is
|
||||
`~psycopg2.extensions.STATUS_IN_TRANSACTION`), e.g. PgBouncer_
|
||||
reports an ``unclean server`` and discards the connection. To
|
||||
avoid this problem you can ensure to terminate the transaction
|
||||
with a `~connection.commit()`/`~connection.rollback()` before
|
||||
closing.
|
||||
|
||||
.. _PgBouncer: http://pgbouncer.projects.postgresql.org/
|
||||
|
||||
.. index::
|
||||
single: Exceptions; In the connection class
|
||||
|
|
|
@ -743,18 +743,15 @@ conn_close(connectionObject *self)
|
|||
Py_BEGIN_ALLOW_THREADS;
|
||||
pthread_mutex_lock(&self->lock);
|
||||
|
||||
/* execute a forced rollback on the connection (but don't check the
|
||||
result, we're going to close the pq connection anyway */
|
||||
if (self->pgconn && self->closed == 1) {
|
||||
PGresult *pgres = NULL;
|
||||
char *error = NULL;
|
||||
|
||||
if (pq_abort_locked(self, &pgres, &error, &_save) < 0) {
|
||||
IFCLEARPGRES(pgres);
|
||||
if (error)
|
||||
free (error);
|
||||
}
|
||||
}
|
||||
/* We used to call pq_abort_locked here, but the idea of issuing a
|
||||
* rollback on close/GC has been considered inappropriate.
|
||||
*
|
||||
* Dropping the connection on the server has the same effect as the
|
||||
* transaction is automatically rolled back. Some middleware, such as
|
||||
* PgBouncer, have problem with connections closed in the middle of the
|
||||
* transaction though: to avoid these problems the transaction should be
|
||||
* closed only in status CONN_STATUS_READY.
|
||||
*/
|
||||
|
||||
if (self->closed == 0)
|
||||
self->closed = 1;
|
||||
|
@ -763,8 +760,8 @@ conn_close(connectionObject *self)
|
|||
PQfinish(self->pgconn);
|
||||
Dprintf("conn_close: PQfinish called");
|
||||
self->pgconn = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&self->lock);
|
||||
Py_END_ALLOW_THREADS;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user