Hi,
I have been looking through the psycopg code trying to understand a few things
and am a bit confused by "isolation level". I understand the concept as far
as postgresql goes just fine, but the psycopg implementation leaves me
confused. It appears to interact with both "autocommit" and "serialise".
First, we have postgresql which provides autocommit and no autocommit modes
for a session and also provides sql isolation levels "read committed" and
"serializable".
Second we have psycopg trying to automagically manage these modes over
a collection of connections and cursors with various calls and properties
on the connection object.
In cursor.c:
begin_pgconn(cursobject *self)
{
const char *query[] = {
NULL,
"BEGIN; SET TRANSACTION ISOLATION LEVEL READ COMMITTED",
"BEGIN; SET TRANSACTION ISOLATION LEVEL SERIALIZABLE",
"BEGIN; SET TRANSACTION ISOLATION LEVEL SERIALIZABLE"
};
...
if (self->isolation_level == 0 || self->keeper->status != KEEPER_READY)
return 0;
...
pgres = PQexec(self->pgconn, query[self->isolation_level]);
I see that isolation level 0 means that psycopg does not try to manage
transactions at all, if I want them I can issue my own begin/end/set queries
or be happy with whatever postgresql gives me.
Isolation level 2 seems to mean that psycopg will do begin/commit
for me with sql isolation level "serializable".
But Isolation level 1 seems to do the same thing. And, there is a strange
interaction with the .autocommit() method:
psyco_curs_autocommit(cursobject *self, PyObject *args)
{
long int ac = 1; /* the default is to set autocommit on */
if (!PyArg_ParseTuple(args, "|l", &ac)) {
...
if (ac) ac = 0;
else ac = 2;
...
curs_switch_isolation_level(self, ac);
So .autocommit() sets isolation level to 2 and .autocommit(<any_nonzero>)
sets isolation level to 0. Which means that there is no way to use
isolation level 1 anyway if you ever call .autocommit(). Also, even if
there was, isolation levels 1 and 2 appear to be the same.
So is there any automatic way to use the sql "read committed" level
and have psyco pg manage transactions?
Is this a bug, maybe isolation level = 1 was meant to allow use of the
often very useful sql "read committed"? Or maybe there needs to be a bit
more explanation somewhere?
As it stands now, setting .autocommit() and manually manageing transactions
and sql isolation levels seems safest.
Comments?
I'm not on the list, so reply directly or I will check the archive. Sorry.
-dg
--
David Gould
If simplicity worked, the world would be overrun with insects.
|