我在Flask和SQLAlchemy中实现以下目的有一个问题:我有一种用Flask编写的博客应用程序,用户可以在其中编写文本块。因此,我有一个用户模型和一个文本块模型,这些文本块必须是唯一的。文本块可以从两个不同的客户端应用程序写入和发送,并且可以同时发生。我需要使时间块的插入和处理具有原子性,以便两个客户端应用程序不会同时插入和处理同一时间块。 型号:
class TextblockModel(db.Model):
__tablename__ = "textblock"
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False)
text = db.Column(db.Text, default="", nullable=False)
user = db.relationship("User", backref=db.backref("texts", lazy=True))
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(255), nullable=False)
email = db.Column(db.String(100), unique=True, nullable=False)
password = db.Column(db.String(255))
对于两个客户端应用程序中的每一个,我都有一个发布端点:
def post1(self):
blocks = insert_block_into_db(request.json, current_user, CLIENTAPP1)
process_blocks(blocks)
def post2(self):
blocks = insert_block_into_db(request.json, current_user, CLIENTAPP2)
process_blocks(blocks)
我需要使文本块的插入和处理原子化。像这样:
def post1(self):
with lock:
blocks = insert_block_into_db(request.json, current_user, WEBAPP1)
process_blocks(blocks)
def post2(self):
with lock:
blocks = insert_block_into_db(request.json, current_user, WEBAPP2)
process_blocks(blocks)
但是我认为普通的Python锁不起作用,因为WSGI产生了多个用于请求处理的进程。此外,我不需要锁定所有内容,而只需锁定与当前用户相关的行。有谁知道我该如何解决?
答案 0 :(得分:0)
如果您正在使用Gunicorn,则可以在preload_app = True
中设置gunicorn.conf
。这样可以确保在工作人员(即进程)之间共享锁。
与Web服务器无关的另一种解决方案是使用NamedAtomicLock。这是一个很棒的软件包,可创建操作系统全局锁。因此,可以在进程之间共享锁。锁在指定目录中创建一个空文件夹用作共享资源。由于创建和删除目录是根据POSIX标准的原子操作,因此该机制允许跨进程锁定。我不确定它是否适用于非UNIX计算机,例如Windows。