PostgreSQL pgdb driver raises "can't rollback" exception
for some reason I'm experiencing the Oper开发者_StackOverflow中文版ational Error with "can't rollback" message when I attempt to roll back my transaction in the following context:
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'))
The driver in use is PGDB.
What is fundamentally wrong here?
You are looking in the wrong place. What does the PostgreSQL log say about what you are doing?
What happens if you exclude the lock statement?
This is what's happening inside 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")
So I suggest you replace your connections[instance].rollback()
call with:
connections[instance]._tnx = False
connections[instance]._cnx.source().execute("ROLLBACK")
to see if that gives you a more informative error message (the except clause inside pgdb is greedy).
Also: check the Postgresql log, it will have probably logged the reason!
Where do you start the transaction? I do see a COMMIT but don't see a BEGIN or START TRANSACTION.
精彩评论