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 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 - Don't build mx.DateTime support if the module can't be imported
(ticket #53). (ticket #53).

View File

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

View File

@ -63,9 +63,11 @@ extern "C" {
/* possible values for isolation_level */ /* possible values for isolation_level */
typedef enum { typedef enum {
ISOLATION_LEVEL_AUTOCOMMIT = 0, ISOLATION_LEVEL_AUTOCOMMIT = 0,
ISOLATION_LEVEL_READ_COMMITTED = 1, ISOLATION_LEVEL_READ_UNCOMMITTED = 1,
ISOLATION_LEVEL_SERIALIZABLE = 2, ISOLATION_LEVEL_READ_COMMITTED = 2,
ISOLATION_LEVEL_REPEATABLE_READ = 3,
ISOLATION_LEVEL_SERIALIZABLE = 4,
} conn_isolation_level_t; } conn_isolation_level_t;
extern HIDDEN PyTypeObject connectionType; 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 (!PyArg_ParseTuple(args, "i", &level)) return NULL;
if (level < 0 || level > 2) { if (level < 0 || level > 4) {
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_ValueError,
"isolation level must be between 0 and 2"); "isolation level must be between 0 and 4");
return NULL; return NULL;
} }

View File

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

View File

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