最近,出于性能原因,我将正在开发的 Web 应用程序从 MySQL 迁移到 PostgreSQL(我需要 PostGIS 提供的功能)。现在经常会遇到如下错误:
current transaction is aborted, commands ignored until end of transaction block
服务器应用程序使用mod_python。该错误发生在呼叫功能中(即为该特定客户端创建新会话的功能)。下面是适当的代码段(异常发生在调用 sessionAppId 的行上:
def hello(req):
req.content_type = "text/json"
req.headers_out.add('Cache-Control', "no-store, no-cache, must-revalidate")
req.headers_out.add('Pragma', "no-cache")
req.headers_out.add('Expires', "-1")
instance = req.hostname.split(".")[0]
cookieSecret = '....' # whatever :-)
receivedCookies = Cookie.get_cookies(req, Cookie.SignedCookie, secret = cookieSecret)
sessionList = receivedCookies.get('sessions', None)
sessionId = str(uuid.uuid4())
if sessionList:
if type(sessionList) is not Cookie.SignedCookie:
return "{status: 'error', errno:1, errmsg:'Permission denied.'}"
else:
sessionList = sessionList.value.split(",")
for x in sessionList[:]:
revisionCookie = receivedCookies.get('rev_' + str(sessionAppId(x, instance)), None)
# more processing here....
# .....
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()
# .....
这是 sessionAppId 本身:
def sessionAppId(sessionId, instance):
cursors[instance].execute("select id from app where type='session' and contents = %s", (sessionId, ))
row = cursors[instance].fetchone()
if row == None:
return 0
else:
return row[0]
一些澄清和附加问题:
- cursors[instance] 和connections[instance] 是数据库连接和在此域名上提供的Web 应用程序实例的光标。 IE。同一服务器为 example1.com 和 example2.com 提供服务,并使用这些字典根据请求所针对的服务器名称来调用相应的数据库。
- 我真的需要锁定 hello() 函数中的表吗?
- hello() 中的大部分代码都需要为每个浏览器选项卡维护一个单独的会话。我找不到仅使用 cookie 的方法,因为打开网站的浏览器选项卡共享 cookie 池。有更好的方法吗?