Revert pre-2.7b1 behaviour of silent rollback on conn.set_isolation_level()

Legacy method is legacy.
This commit is contained in:
Daniele Varrazzo 2017-02-16 02:40:21 +00:00
parent 20c9c17457
commit b5d80b609d
4 changed files with 36 additions and 17 deletions

2
NEWS
View File

@ -54,8 +54,6 @@ Other changes:
- `~connection.isolation_level` doesn't read from the database but will return
`~psycopg2.extensions.ISOLATION_LEVEL_DEFAULT` if no value was set on the
connection.
- `~connection.set_isolation_level()` will throw an exception if executed
inside a transaction; previously it would have silently rolled it back.
- Empty arrays no more converted into lists if they don't have a type attached
(:ticket:`#506`)

View File

@ -480,8 +480,9 @@ The ``connection`` class
.. note::
From version 2.4.2, `set_session()` and `autocommit` offer
finer control on the transaction characteristics.
This is a legacy method mixing `~conn.isolation_level` and
`~conn.autocommit`. Using the respective properties is a better
option.
Set the `transaction isolation level`_ for the current session.
The level defines the different phenomena that can happen in the
@ -501,12 +502,6 @@ The ``connection`` class
See also :ref:`transactions-control`.
.. versionchanged:: 2.7
the function must be called outside a transaction; previously it
would have executed an implicit :sql:`ROLLBACK`; it will now raise
an exception.
.. index::
pair: Client; Encoding

View File

@ -698,7 +698,9 @@ psyco_conn_set_isolation_level(connectionObject *self, PyObject *args)
int level = 1;
PyObject *pyval = NULL;
_set_session_checks(self, set_isolation_level);
EXC_IF_CONN_CLOSED(self);
EXC_IF_CONN_ASYNC(self, "isolation_level");
EXC_IF_TPC_PREPARED(self, "isolation_level");
if (!PyArg_ParseTuple(args, "O", &pyval)) return NULL;
@ -717,6 +719,10 @@ psyco_conn_set_isolation_level(connectionObject *self, PyObject *args)
}
}
if (0 > conn_rollback(self)) {
return NULL;
}
if (level == 0) {
if (0 > conn_set_session(self, 1,
ISOLATION_LEVEL_DEFAULT, self->readonly, self->deferrable)) {

View File

@ -560,14 +560,34 @@ class IsolationLevelsTestCase(ConnectingTestCase):
self.assertEqual(ext.TRANSACTION_STATUS_INTRANS,
conn.get_transaction_status())
# changed in psycopg 2.7
self.assertRaises(psycopg2.ProgrammingError,
conn.set_isolation_level,
ext.ISOLATION_LEVEL_SERIALIZABLE)
self.assertEqual(ext.TRANSACTION_STATUS_INTRANS,
conn.set_isolation_level(
psycopg2.extensions.ISOLATION_LEVEL_SERIALIZABLE)
self.assertEqual(psycopg2.extensions.TRANSACTION_STATUS_IDLE,
conn.get_transaction_status())
cur.execute("select count(*) from isolevel;")
self.assertEqual(0, cur.fetchone()[0])
cur.execute("insert into isolevel values (10);")
self.assertEqual(psycopg2.extensions.TRANSACTION_STATUS_INTRANS,
conn.get_transaction_status())
conn.set_isolation_level(
psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT)
self.assertEqual(psycopg2.extensions.TRANSACTION_STATUS_IDLE,
conn.get_transaction_status())
cur.execute("select count(*) from isolevel;")
self.assertEqual(0, cur.fetchone()[0])
cur.execute("insert into isolevel values (10);")
self.assertEqual(psycopg2.extensions.TRANSACTION_STATUS_IDLE,
conn.get_transaction_status())
conn.set_isolation_level(
psycopg2.extensions.ISOLATION_LEVEL_READ_COMMITTED)
self.assertEqual(psycopg2.extensions.TRANSACTION_STATUS_IDLE,
conn.get_transaction_status())
cur.execute("select count(*) from isolevel;")
self.assertEqual(1, cur.fetchone()[0])
self.assertEqual(conn.isolation_level,
ext.ISOLATION_LEVEL_DEFAULT)
psycopg2.extensions.ISOLATION_LEVEL_READ_COMMITTED)
def test_isolation_level_autocommit(self):
cnn1 = self.connect()