我在使用带有两个工作线程和nginx的uwsgi的MySQL的flask-sqlalchemy中导致并发性问题。烧瓶:使用flask-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通过适当的代码流并将new_contact合并到sessionA中。
同时,requestB经过相同的代码路径,其中contact为None(因为sessionA尚未提交)并将new_contact合并到sessionB中。
然后sessionA在sessionB之前提交。当sessionB进行提交时,它会违反PK。
我们可以做其他事情吗?除了抓住PK违规行为并据此做出反应?