繁体   English   中英

如何锁定Django中的关键部分?

[英]How to lock a critical section in Django?

我找不到一个很好的方法来锁定Django中的一个关键部分。 我可以使用锁或信号量,但python实现仅用于线程,因此如果生产服务器分叉那么那些将不会被尊重。 有没有人知道一种方式(我现在正在考虑posix信号量)以保证跨进程的锁定,或禁止这种方式阻止Django服务器分叉。

如果使用RDBMS,则可以使用其“LOCK”机制。 例如,当一个“SELECT FOR UPDATE”事务锁定一行时,与该行的另一个“SELECT FOR UPDATE”事务必须等待。

# You can use any Python DB API.
[SQL] BEGIN;

[SQL] SELECT col_name FROM table_name where id = 1 FOR UPDATE;

[Process some python code]

[SQL] COMMIT;

使用Django内置的select_for_update函数。
https://docs.djangoproject.com/en/1.8/ref/models/querysets/#select-for-update
来自文档:
返回一个查询集,该查询集将锁定行直到事务结束,在支持的数据库上生成SELECT ... FOR UPDATE SQL语句。

例如:

entries = Entry.objects.select_for_update().filter(author=request.user)

所有匹配的条目将被锁定,直到事务块结束,这意味着将阻止其他事务更改或获取锁定。

在您的应用突然需要在多个服务上运行时,您需要一个分布式锁管理器。 我为此目的写了一个elock 更大的 ,其他人选择忽略每个建议,并使用memcached完成相同的操作。

请不要将memcached用于轻量级咨询锁定。 它旨在忘记一些东西。

我喜欢在我制作网络应用程序时假装文件系统不存在。 使规模更好。

你可以使用简单的文件锁定为互斥机制,看我的食谱在这里 它不适合所有场景,但是你没有说明为什么要使用这种类型的锁定。

我最终得到了一个我自己涉及文件锁定的解决方案。 如果这里的任何人最终使用它,请记住咨询锁和NFS不能很好地混合,所以请保持本地化。 此外,这是一个阻塞锁,如果你想乱搞循环并不断检查,那么代码中有指令。

import os
import fcntl

class DjangoLock:

    def __init__(self, filename):
        self.filename = filename
        # This will create it if it does not exist already
        self.handle = open(filename, 'w')

    # flock() is a blocking call unless it is bitwise ORed with LOCK_NB to avoid blocking 
    # on lock acquisition.  This blocking is what I use to provide atomicity across forked
    # Django processes since native python locks and semaphores only work at the thread level
    def acquire(self):
        fcntl.flock(self.handle, fcntl.LOCK_EX)

    def release(self):
        fcntl.flock(self.handle, fcntl.LOCK_UN)

    def __del__(self):
        self.handle.close()

Usage:

lock = DJangoLock('/tmp/djangolock.tmp')
lock.acquire()
try:
    pass
finally:
    lock.release()

我没有写这篇文章,但我发现它面对同样的问题是非常有帮助的:

http://chris-lamb.co.uk/2010/06/07/distributing-locking-python-and-redis/

基本上,您使用Redis服务器来创建公开锁定功能的中央服务器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM