Use all the isolation levels accepted by PostgreSQL

In PG 9.1 repeatable read and serializable are distinct levels.
This commit is contained in:
Daniele Varrazzo 2011-05-11 12:51:44 +01:00
parent 834c7d1288
commit 19ec8809fd
6 changed files with 35 additions and 25 deletions

2
NEWS
View File

@ -1,6 +1,8 @@
What's new in psycopg 2.4.2
---------------------------
- Allow using the isolation level "repeatable read" which is distinct
from "serializable" in PostgreSQL 9.1.
- Don't build mx.DateTime support if the module can't be imported
(ticket #53).

View File

@ -69,12 +69,10 @@ except ImportError:
"""Isolation level values."""
ISOLATION_LEVEL_AUTOCOMMIT = 0
ISOLATION_LEVEL_READ_COMMITTED = 1
ISOLATION_LEVEL_SERIALIZABLE = 2
# PostgreSQL maps the the other standard values to already defined levels
ISOLATION_LEVEL_REPEATABLE_READ = ISOLATION_LEVEL_SERIALIZABLE
ISOLATION_LEVEL_READ_UNCOMMITTED = ISOLATION_LEVEL_READ_COMMITTED
ISOLATION_LEVEL_READ_UNCOMMITTED = 1
ISOLATION_LEVEL_READ_COMMITTED = 2
ISOLATION_LEVEL_REPEATABLE_READ = 3
ISOLATION_LEVEL_SERIALIZABLE = 4
"""psycopg connection status values."""
STATUS_SETUP = 0

View File

@ -64,8 +64,10 @@ extern "C" {
/* possible values for isolation_level */
typedef enum {
ISOLATION_LEVEL_AUTOCOMMIT = 0,
ISOLATION_LEVEL_READ_COMMITTED = 1,
ISOLATION_LEVEL_SERIALIZABLE = 2,
ISOLATION_LEVEL_READ_UNCOMMITTED = 1,
ISOLATION_LEVEL_READ_COMMITTED = 2,
ISOLATION_LEVEL_REPEATABLE_READ = 3,
ISOLATION_LEVEL_SERIALIZABLE = 4,
} conn_isolation_level_t;
extern HIDDEN PyTypeObject connectionType;

View File

@ -400,9 +400,9 @@ psyco_conn_set_isolation_level(connectionObject *self, PyObject *args)
if (!PyArg_ParseTuple(args, "i", &level)) return NULL;
if (level < 0 || level > 2) {
if (level < 0 || level > 4) {
PyErr_SetString(PyExc_ValueError,
"isolation level must be between 0 and 2");
"isolation level must be between 0 and 4");
return NULL;
}

View File

@ -408,7 +408,9 @@ pq_begin_locked(connectionObject *conn, PGresult **pgres, char **error,
{
const char *query[] = {
NULL,
"BEGIN; SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED",
"BEGIN; SET TRANSACTION ISOLATION LEVEL READ COMMITTED",
"BEGIN; SET TRANSACTION ISOLATION LEVEL REPEATABLE READ",
"BEGIN; SET TRANSACTION ISOLATION LEVEL SERIALIZABLE"};
int result;

View File

@ -201,24 +201,30 @@ class IsolationLevelsTestCase(unittest.TestCase):
def test_set_isolation_level(self):
conn = self.connect()
curs = conn.cursor()
conn.set_isolation_level(
psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT)
self.assertEqual(conn.isolation_level,
psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT)
for name, level in (
(None, psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT),
('read uncommitted', psycopg2.extensions.ISOLATION_LEVEL_READ_UNCOMMITTED),
('read committed', psycopg2.extensions.ISOLATION_LEVEL_READ_COMMITTED),
('repeatable read', psycopg2.extensions.ISOLATION_LEVEL_REPEATABLE_READ),
('serializable', psycopg2.extensions.ISOLATION_LEVEL_SERIALIZABLE),
):
conn.set_isolation_level(level)
self.assertEqual(conn.isolation_level, level)
conn.set_isolation_level(
psycopg2.extensions.ISOLATION_LEVEL_READ_COMMITTED)
self.assertEqual(conn.isolation_level,
psycopg2.extensions.ISOLATION_LEVEL_READ_COMMITTED)
curs.execute('show transaction_isolation;')
got_name = curs.fetchone()[0]
conn.set_isolation_level(
psycopg2.extensions.ISOLATION_LEVEL_SERIALIZABLE)
self.assertEqual(conn.isolation_level,
psycopg2.extensions.ISOLATION_LEVEL_SERIALIZABLE)
if name is None:
curs.execute('show default_transaction_isolation;')
name = curs.fetchone()[0]
self.assertEqual(name, got_name)
conn.commit()
self.assertRaises(ValueError, conn.set_isolation_level, -1)
self.assertRaises(ValueError, conn.set_isolation_level, 3)
self.assertRaises(ValueError, conn.set_isolation_level, 5)
def test_set_isolation_level_abort(self):
conn = self.connect()