我正在使用Django + db.sqlite3 + uwsgi (+ nginx)。
非常感谢!
编辑1:
太棒了,当然Django本身解决了这个问题。比我预想的要容易得多。很高兴我问了一下周围的人!
这是我用黄色记号笔标出来的手册页面http://marker.to/W0CbtZ关于事务的版本https://docs.djangoproject.com/en/1.7/topics/db/transactions/。
谢谢,IRC :-)
编辑2:
实际上我正在寻找一个数据库锁,使得所有进程都等待直到轮到它们。
今天我学到了什么,现在我已经实现了:
try:
with transaction.atomic():
foo(obj)
obj.save() # (*)
except IntegrityError:
print "debug information"
所以我永远不会遇到不一致的数据库。但现在,(*)会抛出异常“OperationalError: database is locked”(而this suggestion也没有帮助)。这是可以理解的,因为许多此类事务正在同时尝试保存到数据库中。我需要的是像...这样的东西。
lock = threading.Lock()
...
with lock:
foo(obj)
obj.save()
但不包括线程,因为它需要锁定所有uwsgi工作进程。
欢迎任何想法。最优雅的方法是什么?现在应该查看手册的哪个部分?我已经搜索过谷歌,并没有找到答案 - 这就是我在这里提问的原因。
非常感谢。
编辑 3:
尽管我使用了 我的线程锁,但仍然有一小部分“OperationalError:database is locked”错误。因此,我实施了 @knbk 的建议,但它没有起作用,以下是输出内容:
up to here all is fine
ALERT! cannot start a transaction within a transaction
Out[]: False
这是我按照 @knbk 的 代码示例 实现的方式:
from django.db import connection
def foobar():
cursor = connection.cursor()
cursor.execute('BEGIN IMMEDIATE') # also tried 'BEGIN EXCLUSIVE'
try:
myObjects = myModel.objects.filter(myFilter="myfilter")
if myCondition(myObjects) > 0:
obj = myObjects[0]
print "up to here all is fine"
obj.save()
except Exception as e:
connection.rollback()
print "ALERT!", e
return False
finally:
connection.commit()
return True
那么...现在怎么办?
编辑4:
我现在已经自己解决了。我编写了一个完整的lockbydir.DLock类,它使用目录存在和年龄-用于跨进程锁定!现在我可以简单地锁定对Django DB的访问,而不管使用哪个DB。非常高兴。也许你想看一下?这是GIT链接:
https://github.com/drandreaskrueger/lockbydir
请查看README文件。甚至有3个GIT播放器可以在浏览器中实时观看代码示例的执行!很棒,不是吗?;-)
感谢您的时间和关注!