Flask:PK违规使用Flask炼金术

2024-10-04 03:29:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我遇到了并发问题,导致MySQL使用uwsgi和两个工作线程以及nginx的sqlalchemy中PK冲突。你知道吗

我用的是有效载荷上的钥匙。如果联系人的密钥存在于数据库中,请更新该记录,否则,请创建一个新记录。你知道吗

这里是设置和我认为正在发生的事情。你知道吗

#project/__init__.py
app = Flask(__name__)
db = SQLAlchemy(app)
from project import views, models

#project/views.py
from project import db

@app.route('/receive', methods = ['POST'])
def receive():

    #Check to see if the contact exists in the database
    contact = models.Contact.getIssue(contact_payload['id'])

    if contact is None:
        #If not in the DB, create a new contact
        new_contact = models.Contact(contact_payload)
        db.session.merge(new_contact)
    else:
        #If in the DB, create an updated representation of this contact
        updated_issue = contact.updateContact(contact_payload)
        db.session.merge(updated_issue)

    ...Some other stuff...

    #Commit to DB
    db.session.commit()

    #Respond
    resp = jsonify({'Result' : 'Success'})
    resp.status_code = 200
    return resp

当我们在同一时间收到同一联系人的两个请求(requestA是12:10:49063,requestB是12:10:49066)时,问题就来了。其中一个请求以PK冲突结束。你知道吗

我怀疑它们来自不同的工作线程,每个请求都从flask-sqlalchemy获得一个作用域会话(sessionA-requestA和sessionB-requestB)。你知道吗

我怀疑这两个会话在请求的开头都不包含任何内容,这些请求现在同时出现在上述代码流中。你知道吗

requestA通过适当的代码流,将新的联系人合并到sessionA中。你知道吗

同时,requestB通过相同的代码路径,其中contact为None(因为sessionA尚未提交),并将新的\u contact合并到sessionB中。你知道吗

然后sessionA在sessionB之前提交。当sessionB去提交时,它会得到PK冲突。你知道吗

除了抓住PK违规并做出相应反应之外,我们还能做些什么吗?你知道吗


Tags: theinprojectappnewdbmodelssession
1条回答
网友
1楼 · 发布于 2024-10-04 03:29:29

您有两种选择:

  1. 抓住PK违例并做出相应的反应,就像你已经说过的那样。

  2. 基于您的id锁定您的事务:这更复杂,您需要一些东西来同步您的锁,比如redis。看看python redis lock。这只是一种选择,这里的解决方案是避免PK的并发。

https://pypi.python.org/pypi/python-redis-lock

相关问题 更多 >