mirror of
https://github.com/psycopg/psycopg2.git
synced 2024-11-23 01:16:34 +03:00
Dropped isolation level from the connection object
Don't issue a SET TRANSACTION ISOLATION LEVEL at every begin: use PG's GUC default, eventually set by set_transaction. Dropped the last query at connection, yay! Method set_isolation_level() and property isolation_level refactored using the new structures, keeping the previous semantic.
This commit is contained in:
parent
389f2cf1d0
commit
c2d1f1f2e6
|
@ -61,15 +61,6 @@ extern "C" {
|
|||
#define psyco_datestyle "SET DATESTYLE TO 'ISO'"
|
||||
#define psyco_transaction_isolation "SHOW default_transaction_isolation"
|
||||
|
||||
/* possible values for isolation_level */
|
||||
typedef enum {
|
||||
ISOLATION_LEVEL_AUTOCOMMIT = 0,
|
||||
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;
|
||||
|
||||
struct connectionObject_notice {
|
||||
|
@ -89,7 +80,6 @@ typedef struct {
|
|||
|
||||
long int closed; /* 1 means connection has been closed;
|
||||
2 that something horrible happened */
|
||||
long int isolation_level; /* isolation level for this connection */
|
||||
long int mark; /* number of commits/rollbacks done so far */
|
||||
int status; /* status of the connection */
|
||||
XidObject *tpc_xid; /* Transaction ID in two-phase commit */
|
||||
|
@ -123,10 +113,16 @@ typedef struct {
|
|||
|
||||
} connectionObject;
|
||||
|
||||
/* map isolation level values into a numeric const */
|
||||
typedef struct {
|
||||
char *name;
|
||||
int value;
|
||||
} IsolationLevel;
|
||||
|
||||
/* C-callable functions in connection_int.c and connection_ext.c */
|
||||
HIDDEN PyObject *conn_text_from_chars(connectionObject *pgconn, const char *str);
|
||||
HIDDEN int conn_get_standard_conforming_strings(PGconn *pgconn);
|
||||
HIDDEN int conn_get_isolation_level(PGresult *pgres);
|
||||
HIDDEN int conn_get_isolation_level(connectionObject *self);
|
||||
HIDDEN int conn_get_protocol_version(PGconn *pgconn);
|
||||
HIDDEN int conn_get_server_version(PGconn *pgconn);
|
||||
HIDDEN PGcancel *conn_get_cancel(PGconn *pgconn);
|
||||
|
|
|
@ -34,6 +34,19 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
/* Mapping from isolation level name to value exposed by Python.
|
||||
* Only used for backward compatibility by the isolation_level property */
|
||||
|
||||
const IsolationLevel conn_isolevels[] = {
|
||||
{"", 0}, /* autocommit */
|
||||
{"read uncommitted", 1},
|
||||
{"read committed", 2},
|
||||
{"repeatable read", 3},
|
||||
{"serializable", 4},
|
||||
{"default", -1},
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
||||
/* Return a new "string" from a char* from the database.
|
||||
*
|
||||
|
@ -358,22 +371,60 @@ exit:
|
|||
return rv;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
conn_get_isolation_level(PGresult *pgres)
|
||||
conn_get_isolation_level(connectionObject *self)
|
||||
{
|
||||
static const char lvl1a[] = "read uncommitted";
|
||||
static const char lvl1b[] = "read committed";
|
||||
int rv;
|
||||
PGresult *pgres;
|
||||
int rv = -1;
|
||||
char *lname;
|
||||
const IsolationLevel *level;
|
||||
|
||||
char *isolation_level = PQgetvalue(pgres, 0, 0);
|
||||
/* this may get called by async connections too: here's your result */
|
||||
if (self->autocommit) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((strcmp(lvl1b, isolation_level) == 0) /* most likely */
|
||||
|| (strcmp(lvl1a, isolation_level) == 0))
|
||||
rv = ISOLATION_LEVEL_READ_COMMITTED;
|
||||
else /* if it's not one of the lower ones, it's SERIALIZABLE */
|
||||
rv = ISOLATION_LEVEL_SERIALIZABLE;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
pthread_mutex_lock(&self->lock);
|
||||
Py_BLOCK_THREADS;
|
||||
|
||||
CLEARPGRES(pgres);
|
||||
if (!psyco_green()) {
|
||||
Py_UNBLOCK_THREADS;
|
||||
pgres = PQexec(self->pgconn, psyco_transaction_isolation);
|
||||
Py_BLOCK_THREADS;
|
||||
} else {
|
||||
pgres = psyco_exec_green(self, psyco_transaction_isolation);
|
||||
}
|
||||
|
||||
if (pgres == NULL || PQresultStatus(pgres) != PGRES_TUPLES_OK) {
|
||||
PyErr_SetString(OperationalError,
|
||||
"can't fetch default_transaction_isolation");
|
||||
goto endlock;
|
||||
}
|
||||
|
||||
/* find the value for the requested isolation level */
|
||||
lname = PQgetvalue(pgres, 0, 0);
|
||||
level = conn_isolevels;
|
||||
while ((++level)->name) {
|
||||
if (0 == strcasecmp(level->name, lname)) {
|
||||
rv = level->value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (-1 == rv) {
|
||||
char msg[256];
|
||||
snprintf(msg, sizeof(msg), "unexpected isolation level: '%s'", lname);
|
||||
PyErr_SetString(OperationalError, msg);
|
||||
}
|
||||
|
||||
endlock:
|
||||
IFCLEARPGRES(pgres);
|
||||
|
||||
Py_UNBLOCK_THREADS;
|
||||
pthread_mutex_unlock(&self->lock);
|
||||
Py_END_ALLOW_THREADS;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
@ -477,24 +528,8 @@ conn_setup(connectionObject *self, PGconn *pgconn)
|
|||
CLEARPGRES(pgres);
|
||||
}
|
||||
|
||||
if (!green) {
|
||||
Py_UNBLOCK_THREADS;
|
||||
pgres = PQexec(pgconn, psyco_transaction_isolation);
|
||||
Py_BLOCK_THREADS;
|
||||
} else {
|
||||
pgres = psyco_exec_green(self, psyco_transaction_isolation);
|
||||
}
|
||||
|
||||
if (pgres == NULL || PQresultStatus(pgres) != PGRES_TUPLES_OK) {
|
||||
PyErr_SetString(OperationalError,
|
||||
"can't fetch default_isolation_level");
|
||||
IFCLEARPGRES(pgres);
|
||||
Py_UNBLOCK_THREADS;
|
||||
pthread_mutex_unlock(&self->lock);
|
||||
Py_BLOCK_THREADS;
|
||||
return -1;
|
||||
}
|
||||
self->isolation_level = conn_get_isolation_level(pgres);
|
||||
/* for reset */
|
||||
self->autocommit = 0;
|
||||
|
||||
Py_UNBLOCK_THREADS;
|
||||
pthread_mutex_unlock(&self->lock);
|
||||
|
@ -779,7 +814,7 @@ _conn_poll_setup_async(connectionObject *self)
|
|||
* expected to manage the transactions himself, by sending
|
||||
* (asynchronously) BEGIN and COMMIT statements.
|
||||
*/
|
||||
self->isolation_level = ISOLATION_LEVEL_AUTOCOMMIT;
|
||||
self->autocommit = 1;
|
||||
|
||||
/* If the datestyle is ISO or anything else good,
|
||||
* we can skip the CONN_STATUS_DATESTYLE step. */
|
||||
|
@ -989,7 +1024,14 @@ conn_set(connectionObject *self, const char *param, const char *value)
|
|||
int
|
||||
conn_set_autocommit(connectionObject *self, int value)
|
||||
{
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
pthread_mutex_lock(&self->lock);
|
||||
|
||||
self->autocommit = value;
|
||||
|
||||
pthread_mutex_unlock(&self->lock);
|
||||
Py_END_ALLOW_THREADS;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -998,33 +1040,54 @@ conn_set_autocommit(connectionObject *self, int value)
|
|||
int
|
||||
conn_switch_isolation_level(connectionObject *self, int level)
|
||||
{
|
||||
PGresult *pgres = NULL;
|
||||
char *error = NULL;
|
||||
int res = 0;
|
||||
int curr_level;
|
||||
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
pthread_mutex_lock(&self->lock);
|
||||
|
||||
/* if the current isolation level is equal to the requested one don't switch */
|
||||
if (self->isolation_level != level) {
|
||||
|
||||
/* if the current isolation level is > 0 we need to abort the current
|
||||
transaction before changing; that all folks! */
|
||||
if (self->isolation_level != ISOLATION_LEVEL_AUTOCOMMIT) {
|
||||
res = pq_abort_locked(self, &pgres, &error, &_save);
|
||||
}
|
||||
self->isolation_level = level;
|
||||
|
||||
Dprintf("conn_switch_isolation_level: switched to level %d", level);
|
||||
if (-1 == (curr_level = conn_get_isolation_level(self))) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&self->lock);
|
||||
Py_END_ALLOW_THREADS;
|
||||
if (curr_level == level) {
|
||||
/* no need to change level */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (res < 0)
|
||||
pq_complete_error(self, &pgres, &error);
|
||||
/* Emulate the previous semantic of set_isolation_level() using the
|
||||
* functions currently available. */
|
||||
|
||||
return res;
|
||||
/* terminate the current transaction if any */
|
||||
pq_abort(self);
|
||||
|
||||
if (level == 0) {
|
||||
if (0 != conn_set(self, "default_transaction_isolation", "default")) {
|
||||
return -1;
|
||||
}
|
||||
if (0 != conn_set_autocommit(self, 1)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* find the name of the requested level */
|
||||
const IsolationLevel *isolevel = conn_isolevels;
|
||||
while ((++isolevel)->name) {
|
||||
if (level == isolevel->value) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isolevel->name) {
|
||||
PyErr_SetString(OperationalError, "bad isolation level value");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (0 != conn_set(self, "default_transaction_isolation", isolevel->name)) {
|
||||
return -1;
|
||||
}
|
||||
if (0 != conn_set_autocommit(self, 0)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
Dprintf("conn_switch_isolation_level: switched to level %d", level);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* conn_set_client_encoding - switch client encoding on connection */
|
||||
|
|
|
@ -198,7 +198,7 @@ psyco_conn_tpc_begin(connectionObject *self, PyObject *args)
|
|||
}
|
||||
|
||||
/* two phase commit and autocommit make no point */
|
||||
if (self->isolation_level == ISOLATION_LEVEL_AUTOCOMMIT) {
|
||||
if (self->autocommit) {
|
||||
PyErr_SetString(ProgrammingError,
|
||||
"tpc_begin can't be called in autocommit mode");
|
||||
goto exit;
|
||||
|
@ -381,50 +381,51 @@ psyco_conn_tpc_recover(connectionObject *self, PyObject *args)
|
|||
|
||||
/* parse a python object into one of the possible isolation level values */
|
||||
|
||||
extern const IsolationLevel conn_isolevels[];
|
||||
|
||||
static const char *
|
||||
_psyco_conn_parse_isolevel(PyObject *pyval)
|
||||
{
|
||||
const char **value = NULL;
|
||||
const char *rv = NULL;
|
||||
const IsolationLevel *value = NULL;
|
||||
|
||||
static const char *isolevels[] = {
|
||||
"", /* autocommit */
|
||||
"read uncommitted",
|
||||
"read committed",
|
||||
"repeatable read",
|
||||
"serializable",
|
||||
"default",
|
||||
NULL };
|
||||
Py_INCREF(pyval); /* for ensure_bytes */
|
||||
|
||||
/* parse from one of the level constants */
|
||||
if (PyInt_Check(pyval)) {
|
||||
long level = PyInt_AsLong(pyval);
|
||||
if (level == -1 && PyErr_Occurred()) { return NULL; }
|
||||
if (level == -1 && PyErr_Occurred()) { goto exit; }
|
||||
if (level < 1 || level > 4) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"isolation_level must be between 1 and 4");
|
||||
return NULL;
|
||||
goto exit;
|
||||
}
|
||||
value = isolevels + level;
|
||||
rv = conn_isolevels[level].name;
|
||||
}
|
||||
|
||||
/* parse from the string -- this includes "default" */
|
||||
else {
|
||||
value = isolevels;
|
||||
while (*(++value)) {
|
||||
int cmp;
|
||||
PyObject *pylevel;
|
||||
if (!(pylevel = Text_FromUTF8(*value))) { return NULL; }
|
||||
cmp = PyObject_RichCompareBool(pylevel, pyval, Py_EQ);
|
||||
Py_DECREF(pylevel);
|
||||
if (-1 == cmp) { return NULL; }
|
||||
if (cmp) { break; }
|
||||
value = conn_isolevels;
|
||||
while ((++value)->name) {
|
||||
if (!(pyval = psycopg_ensure_bytes(pyval))) {
|
||||
goto exit;
|
||||
}
|
||||
if (0 == strcasecmp(value->name, Bytes_AS_STRING(pyval))) {
|
||||
rv = value->name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!*value) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"bad value for isolation_level"); /* TODO: emit value */
|
||||
if (!rv) {
|
||||
char msg[256];
|
||||
snprintf(msg, sizeof(msg),
|
||||
"bad value for isolation_level: '%s'", Bytes_AS_STRING(pyval));
|
||||
PyErr_SetString(PyExc_ValueError, msg);
|
||||
}
|
||||
}
|
||||
return *value;
|
||||
|
||||
exit:
|
||||
Py_XDECREF(pyval);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* convert True/False/"default" into a C string */
|
||||
|
@ -553,6 +554,17 @@ psyco_conn_autocommit_set(connectionObject *self, PyObject *pyvalue)
|
|||
}
|
||||
|
||||
|
||||
/* isolation_level - return the current isolation level */
|
||||
|
||||
static PyObject *
|
||||
psyco_conn_isolation_level_get(connectionObject *self)
|
||||
{
|
||||
int rv = conn_get_isolation_level(self);
|
||||
if (-1 == rv) { return NULL; }
|
||||
return PyInt_FromLong((long)rv);
|
||||
}
|
||||
|
||||
|
||||
/* set_isolation_level method - switch connection isolation level */
|
||||
|
||||
#define psyco_conn_set_isolation_level_doc \
|
||||
|
@ -920,9 +932,6 @@ static struct PyMemberDef connectionObject_members[] = {
|
|||
#ifdef PSYCOPG_EXTENSIONS
|
||||
{"closed", T_LONG, offsetof(connectionObject, closed), READONLY,
|
||||
"True if the connection is closed."},
|
||||
{"isolation_level", T_LONG,
|
||||
offsetof(connectionObject, isolation_level), READONLY,
|
||||
"The current isolation level."},
|
||||
{"encoding", T_STRING, offsetof(connectionObject, encoding), READONLY,
|
||||
"The current client encoding."},
|
||||
{"notices", T_OBJECT, offsetof(connectionObject, notice_list), READONLY},
|
||||
|
@ -968,6 +977,10 @@ static struct PyGetSetDef connectionObject_getsets[] = {
|
|||
(getter)psyco_conn_autocommit_get,
|
||||
(setter)psyco_conn_autocommit_set,
|
||||
psyco_conn_autocommit_doc },
|
||||
{ "isolation_level",
|
||||
(getter)psyco_conn_isolation_level_get,
|
||||
(setter)NULL,
|
||||
"The current isolation level." },
|
||||
#endif
|
||||
{NULL}
|
||||
};
|
||||
|
|
|
@ -456,7 +456,7 @@ psyco_curs_execute(cursorObject *self, PyObject *args, PyObject *kwargs)
|
|||
NULL, NULL);
|
||||
return NULL;
|
||||
}
|
||||
if (self->conn->isolation_level == ISOLATION_LEVEL_AUTOCOMMIT) {
|
||||
if (self->conn->autocommit) {
|
||||
psyco_set_error(ProgrammingError, self,
|
||||
"can't use a named cursor outside of transactions", NULL, NULL);
|
||||
return NULL;
|
||||
|
|
|
@ -76,7 +76,7 @@ HIDDEN int lobject_close(lobjectObject *self);
|
|||
return NULL; }
|
||||
|
||||
#define EXC_IF_LOBJ_LEVEL0(self) \
|
||||
if (self->conn->isolation_level == 0) { \
|
||||
if (self->conn->autocommit) { \
|
||||
psyco_set_error(ProgrammingError, NULL, \
|
||||
"can't use a lobject outside of transactions", NULL, NULL); \
|
||||
return NULL; \
|
||||
|
|
|
@ -252,7 +252,7 @@ lobject_close_locked(lobjectObject *self, char **error)
|
|||
break;
|
||||
}
|
||||
|
||||
if (self->conn->isolation_level == ISOLATION_LEVEL_AUTOCOMMIT ||
|
||||
if (self->conn->autocommit ||
|
||||
self->conn->mark != self->mark ||
|
||||
self->fd == -1)
|
||||
return 0;
|
||||
|
|
|
@ -51,7 +51,7 @@ psyco_lobj_close(lobjectObject *self, PyObject *args)
|
|||
closing the current transaction is equivalent to close all the
|
||||
opened large objects */
|
||||
if (!lobject_is_closed(self)
|
||||
&& self->conn->isolation_level != ISOLATION_LEVEL_AUTOCOMMIT
|
||||
&& !self->conn->autocommit
|
||||
&& self->conn->mark == self->mark)
|
||||
{
|
||||
Dprintf("psyco_lobj_close: closing lobject at %p", self);
|
||||
|
@ -331,7 +331,7 @@ lobject_setup(lobjectObject *self, connectionObject *conn,
|
|||
{
|
||||
Dprintf("lobject_setup: init lobject object at %p", self);
|
||||
|
||||
if (conn->isolation_level == ISOLATION_LEVEL_AUTOCOMMIT) {
|
||||
if (conn->autocommit) {
|
||||
psyco_set_error(ProgrammingError, NULL,
|
||||
"can't use a lobject outside of transactions", NULL, NULL);
|
||||
return -1;
|
||||
|
|
|
@ -406,30 +406,17 @@ int
|
|||
pq_begin_locked(connectionObject *conn, PGresult **pgres, char **error,
|
||||
PyThreadState **tstate)
|
||||
{
|
||||
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;
|
||||
|
||||
Dprintf("pq_begin_locked: pgconn = %p, isolevel = %ld, status = %d",
|
||||
conn->pgconn, conn->isolation_level, conn->status);
|
||||
Dprintf("pq_begin_locked: pgconn = %p, autocommit = %d, status = %d",
|
||||
conn->pgconn, conn->autocommit, conn->status);
|
||||
|
||||
if (conn->autocommit) {
|
||||
Dprintf("pq_begin_locked: autocommit");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (conn->isolation_level == ISOLATION_LEVEL_AUTOCOMMIT
|
||||
|| conn->status != CONN_STATUS_READY) {
|
||||
if (conn->autocommit || conn->status != CONN_STATUS_READY) {
|
||||
Dprintf("pq_begin_locked: transaction in progress");
|
||||
return 0;
|
||||
}
|
||||
|
||||
result = pq_execute_command_locked(conn, query[conn->isolation_level],
|
||||
pgres, error, tstate);
|
||||
result = pq_execute_command_locked(conn, "BEGIN;", pgres, error, tstate);
|
||||
if (result == 0)
|
||||
conn->status = CONN_STATUS_BEGIN;
|
||||
|
||||
|
@ -449,11 +436,10 @@ pq_commit(connectionObject *conn)
|
|||
PGresult *pgres = NULL;
|
||||
char *error = NULL;
|
||||
|
||||
Dprintf("pq_commit: pgconn = %p, isolevel = %ld, status = %d",
|
||||
conn->pgconn, conn->isolation_level, conn->status);
|
||||
Dprintf("pq_commit: pgconn = %p, autocommit = %d, status = %d",
|
||||
conn->pgconn, conn->autocommit, conn->status);
|
||||
|
||||
if (conn->isolation_level == ISOLATION_LEVEL_AUTOCOMMIT
|
||||
|| conn->status != CONN_STATUS_BEGIN) {
|
||||
if (conn->autocommit || conn->status != CONN_STATUS_BEGIN) {
|
||||
Dprintf("pq_commit: no transaction to commit");
|
||||
return 0;
|
||||
}
|
||||
|
@ -485,11 +471,10 @@ pq_abort_locked(connectionObject *conn, PGresult **pgres, char **error,
|
|||
{
|
||||
int retvalue = -1;
|
||||
|
||||
Dprintf("pq_abort_locked: pgconn = %p, isolevel = %ld, status = %d",
|
||||
conn->pgconn, conn->isolation_level, conn->status);
|
||||
Dprintf("pq_abort_locked: pgconn = %p, autocommit = %d, status = %d",
|
||||
conn->pgconn, conn->autocommit, conn->status);
|
||||
|
||||
if (conn->isolation_level == ISOLATION_LEVEL_AUTOCOMMIT
|
||||
|| conn->status != CONN_STATUS_BEGIN) {
|
||||
if (conn->autocommit || conn->status != CONN_STATUS_BEGIN) {
|
||||
Dprintf("pq_abort_locked: no transaction to abort");
|
||||
return 0;
|
||||
}
|
||||
|
@ -514,11 +499,10 @@ pq_abort(connectionObject *conn)
|
|||
PGresult *pgres = NULL;
|
||||
char *error = NULL;
|
||||
|
||||
Dprintf("pq_abort: pgconn = %p, isolevel = %ld, status = %d",
|
||||
conn->pgconn, conn->isolation_level, conn->status);
|
||||
Dprintf("pq_abort: pgconn = %p, autocommit = %d, status = %d",
|
||||
conn->pgconn, conn->autocommit, conn->status);
|
||||
|
||||
if (conn->isolation_level == ISOLATION_LEVEL_AUTOCOMMIT
|
||||
|| conn->status != CONN_STATUS_BEGIN) {
|
||||
if (conn->autocommit || conn->status != CONN_STATUS_BEGIN) {
|
||||
Dprintf("pq_abort: no transaction to abort");
|
||||
return 0;
|
||||
}
|
||||
|
@ -554,13 +538,12 @@ pq_reset_locked(connectionObject *conn, PGresult **pgres, char **error,
|
|||
{
|
||||
int retvalue = -1;
|
||||
|
||||
Dprintf("pq_reset_locked: pgconn = %p, isolevel = %ld, status = %d",
|
||||
conn->pgconn, conn->isolation_level, conn->status);
|
||||
Dprintf("pq_reset_locked: pgconn = %p, autocommit = %d, status = %d",
|
||||
conn->pgconn, conn->autocommit, conn->status);
|
||||
|
||||
conn->mark += 1;
|
||||
|
||||
if (conn->isolation_level != ISOLATION_LEVEL_AUTOCOMMIT
|
||||
&& conn->status == CONN_STATUS_BEGIN) {
|
||||
if (!conn->autocommit && conn->status == CONN_STATUS_BEGIN) {
|
||||
retvalue = pq_execute_command_locked(conn, "ABORT", pgres, error, tstate);
|
||||
if (retvalue != 0) return retvalue;
|
||||
}
|
||||
|
@ -585,8 +568,8 @@ pq_reset(connectionObject *conn)
|
|||
PGresult *pgres = NULL;
|
||||
char *error = NULL;
|
||||
|
||||
Dprintf("pq_reset: pgconn = %p, isolevel = %ld, status = %d",
|
||||
conn->pgconn, conn->isolation_level, conn->status);
|
||||
Dprintf("pq_reset: pgconn = %p, autocommit = %d, status = %d",
|
||||
conn->pgconn, conn->autocommit, conn->status);
|
||||
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
pthread_mutex_lock(&conn->lock);
|
||||
|
|
|
@ -105,6 +105,7 @@ typedef unsigned long Py_uhash_t;
|
|||
|
||||
#if PY_MAJOR_VERSION > 2
|
||||
#define PyInt_Type PyLong_Type
|
||||
#define PyInt_Check PyLong_Check
|
||||
#define PyInt_AsLong PyLong_AsLong
|
||||
#define PyInt_FromLong PyLong_FromLong
|
||||
#define PyInt_FromSsize_t PyLong_FromSsize_t
|
||||
|
|
Loading…
Reference in New Issue
Block a user