avr*_*mov 2 python mysql django
我正在共享主机方案上运行一个小型Web应用程序.我有一个"工人功能",其中包含一个无限循环; 循环检查数据库中的任务队列以查找要执行的新操作.这需要使用@transaction.commit_manually以击败Django的缓存并获得每次迭代的最新信息.
我最近实现了数据库日志记录,因此需要使用保存点来引入我的worker函数 - 这样,如果出现任何问题,我可以回滚到一个好的保存点,登录到数据库,继续直到我到达最终 transaction.commit()
现在,与我的开发服务器不同,生产服务器给出了错误:
DatabaseError: (1305, 'SAVEPOINT s140364713719520_x1 does not exist')
Run Code Online (Sandbox Code Playgroud)
指向transaction.savepoint_rollback()一个except块中的调用(参见下面的源代码).开发服务器没有这样的问题; 如果我输入transaction.savepoint()交互式shell ,生产服务器会愉快地生成保存点ID .
这是我的代码的大纲,如果它有任何帮助; 我试着保持简洁.
如果那里有任何仁慈的Python专家,请帮助我.我对此感到非常沮丧,虽然我觉得我在以冷静的方式处理它时做得相当不错.
saa*_*aaj 11
我有同样偶然反复出现的令人讨厌的错误:
OperationalError: (1305, 'SAVEPOINT {{name}} does not exist')
Run Code Online (Sandbox Code Playgroud)
谷歌和谷歌没有说清楚,除了它是一种"正常"的并发问题.因此,它是非确定性的,难以在开发环境中重现.
幸运的是,我能够通过使生产应用程序日志记录足够详细来进行本地化.
在MySQL中,有些操作可以隐式结束事务:
CREATE TABLE,ALTER TABLE等)导致隐式提交.众所周知,MySQL中的DDL不是事务性的,OperationalError: (1213, 'Deadlock found when trying to get lock; try restarting transaction')并OperationalError: (1205, 'Lock wait timeout exceeded; try restarting transaction')导致隐式回滚.所以第二种情况确实有些"正常".它可以用以下代码表示:
# db is an example database connection object, which
# - supports nested (stacked) transactions,
# - has autocommit on.
db.begin() # START TRANSACTION
try:
# no-conflict op
db.update()
db.begin() # SAVEPOINT sp1
try:
# conflict op,
# e.g. attempt to change exclusively locked rows by another transaction
db.update()
db.commit() # RELEASE SAVEPOINT sp1
except:
# Everything interesting happens here:
# - the change attempt failed with OperationalError: (1213, 'Deadlock...'),
# - the transaction is rolled back with all the savepoints,
# - next line will attempt to rollback to savepoint which no longer exists,
# - so will raise OperationalError: (1305, 'SAVEPOINT sp1 does not exist'),
# - which will shadow the original exception.
db.rollback() # ROLLBACK TO SAVEPOINT sp1
raise
db.commit() # COMMIT
except:
db.rollback() # ROLLBACK
raise
Run Code Online (Sandbox Code Playgroud)
请注意,上面提到的关于异常阴影的内容是针对Python 2的.Python 3实现了异常链接,并且在死锁的情况下,回溯将具有所有相关信息.