PostgreSQL pgdb 驱动引发 “无法回滚” 异常

1 投票
3 回答
981 浏览
提问于 2025-04-15 20:15

我在尝试回滚我的事务时,遇到了一个操作错误,提示“无法回滚”。这是在以下情况下发生的:

try:
    cursors[instance].execute("lock revision, app, timeout IN SHARE MODE")
    cursors[instance].execute("insert into app (type, active, active_revision, contents, z) values ('session', true, %s, %s, 0) returning id", (cRevision, sessionId))
    sAppId = cursors[instance].fetchone()[0]
    cursors[instance].execute("insert into revision (app_id, type) values (%s, 'active')", (sAppId,))
    cursors[instance].execute("insert into timeout (app_id, last_seen) values (%s, now())", (sAppId,))
    connections[instance].commit()
except pgdb.DatabaseError, e:
    connections[instance].rollback()
    return "{status: 'error', errno:4, errmsg: \"%s\"}"%(str(e).replace('\"', '\\"').replace('\n', '\\n').replace('\r', '\\r'))

我使用的驱动程序是PGDB。

这里到底出了什么根本性的问题呢?

3 个回答

0

你是从哪里开始这个事务的?我看到有一个提交(COMMIT),但是没有看到开始(BEGIN)或者开始事务(START TRANSACTION)。

1

你找错地方了。你看看PostgreSQL的日志里是怎么说你正在做的事情的?

0

如果你不使用锁定语句,会发生什么呢?

在pgdb.py文件里,事情是这样的:

def rollback(self):
    """Roll back to the start of any pending transaction."""
    if self._cnx:
        if self._tnx:
            self._tnx = False
            try:
                self._cnx.source().execute("ROLLBACK")
            except Exception:
                raise OperationalError("can't rollback")
    else:
        raise OperationalError("connection has been closed")

所以我建议你把你的 connections[instance].rollback() 这行代码换成:

connections[instance]._tnx = False
connections[instance]._cnx.source().execute("ROLLBACK")

这样做可能会给你一个更详细的错误信息(pgdb里的异常处理是比较贪心的)。

另外:检查一下Postgresql的日志,里面可能记录了原因!

撰写回答