Пример #1
0
static PyObject *
psyco_conn_isolation_level_get(connectionObject *self)
{
    int rv;

    EXC_IF_CONN_CLOSED(self);
    EXC_IF_TPC_PREPARED(self, set_isolation_level);

    rv = conn_get_isolation_level(self);
    if (-1 == rv) { return NULL; }
    return PyInt_FromLong((long)rv);
}
Пример #2
0
RAISES_NEG int
conn_switch_isolation_level(connectionObject *self, int level)
{
    PGresult *pgres = NULL;
    char *error = NULL;
    int curr_level;
    int ret = -1;

    /* use only supported levels on older PG versions */
    if (self->server_version < 80000) {
        if (level == ISOLATION_LEVEL_READ_UNCOMMITTED)
            level = ISOLATION_LEVEL_READ_COMMITTED;
        else if (level == ISOLATION_LEVEL_REPEATABLE_READ)
            level = ISOLATION_LEVEL_SERIALIZABLE;
    }

    if (-1 == (curr_level = conn_get_isolation_level(self))) {
        return -1;
    }

    if (curr_level == level) {
        /* no need to change level */
        return 0;
    }

    /* Emulate the previous semantic of set_isolation_level() using the
     * functions currently available. */

    Py_BEGIN_ALLOW_THREADS;
    pthread_mutex_lock(&self->lock);

    /* terminate the current transaction if any */
    if ((ret = pq_abort_locked(self, &pgres, &error, &_save))) {
        goto endlock;
    }

    if (level == 0) {
        if ((ret = pq_set_guc_locked(self,
                "default_transaction_isolation", "default",
                &pgres, &error, &_save))) {
            goto endlock;
        }
        self->autocommit = 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) {
            ret = -1;
            error = strdup("bad isolation level value");
            goto endlock;
        }

        if ((ret = pq_set_guc_locked(self,
                "default_transaction_isolation", isolevel->name,
                &pgres, &error, &_save))) {
            goto endlock;
        }
        self->autocommit = 0;
    }

    Dprintf("conn_switch_isolation_level: switched to level %d", level);

endlock:
    pthread_mutex_unlock(&self->lock);
    Py_END_ALLOW_THREADS;

    if (ret < 0) {
        pq_complete_error(self, &pgres, &error);
    }

    return ret;
}