强制 Django 提交
设置:
- Python 脚本 A 每 15 分钟将数据插入数据库
- Python 脚本 B 每隔几分钟从数据库查询一些最新条目
两者都使用Django的ORM,运行在同一台机器上并使用本地MySQL数据库。
问题:
B 会获取条目(最新条目除外),即使 A 在分钟之前保存它。
我怀疑A没有关闭事务,因此B看到数据库没有最后一个条目。事实上,在检查 MySQL 日志时,我注意到每个 INSERT
的commit
发生在下一个 INSERT
之前。
尽管它应该是多余的,但我将 @commit_on_success
装饰器添加到包含 save()
的 A 函数中,但它没有帮助。
如何强制 Django(或 MySQL?!)在 save()
之后立即提交?
更新:
我发现提交确实发生了 - 我被误导相信它们没有发生,因为 MySQL的通用查询日志只有1秒分辨率。
鉴于此和其他新信息,我在这里重新提出了问题 。
Setup:
- Python script A inserts data to a database every 15 minutes
- Python script B queries a few of the latest entries from the database every few minutes
Both use Django's ORM, run on the same machine and use a local MySQL database.
The Problem:
B fetches entries, except for the latest one, even though A saves it minutes before.
I suspected that A doesn't close the transaction, thus B sees the database without the last entry. Indeed when examining the MySQL logs, I noticed the commit
for each INSERT
happens right before the next INSERT
.
Even though it's supposed to be redundant, I added @commit_on_success
decorator to the A function that includes the save()
, but it did not help.
How can I force Django (or MySQL?!) to commit right after the save()
?
UPDATE:
I discovered that the commits DO happen - I was mislead to believe they don't because MySQL's General Query Log only has 1 sec resolution.
In light of this and other new information, I've reasked the question here.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以使用
commit_manually
装饰器并在需要时调用它。直接来自文档:
这回答了您提出的问题,尽管我想知道是否还有其他原因在起作用。
注意:
commit_manually
在 1.6 并在 1.8。You can use the
commit_manually
decorator and call it whenever you want.Straight from the documentation:
This answers the question you asked, though I wonder if there might be something else at work.
NOTE:
commit_manually
was deprecated in 1.6 and removed in 1.8.该问题是由于MySQL默认具有REPEATABLE-READ事务隔离级别引起的。这意味着相同的查询预计会返回相同的值。改变不会回来。您可以在此处执行两件事:
Model.objects.update()
就可以了。The problem is caused by that MySQL by default has a REPEATABLE-READ transaction isolation level. That means that the same query is expected to return the same values. Changes won't return. You can do two things here:
Model.objects.update()
does the trick.