2015-11-03 3 views
3

У меня проблемы с параллелизмом, приводящие к нарушениям ПК в flask-sqlalchemy с MySQL, используя uwsgi с двумя рабочими потоками и nginx.Кол-во: Нарушения ПК Использование фляжки-sqlalchemy

Я использую ключи, которые поступают из полезной нагрузки. Если контакт входит в ключ, который существует в базе данных, обновите запись, если нет, создайте новую запись.

Вот установка и то, что я думаю, происходит.

#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). Один из запросов заканчивается нарушением ПК.

Я подозреваю, что они приходят в разные рабочие потоки, и каждый запрос получает сеанс с областью (sessionA - requestA и sessionB - requestB) из flask-sqlalchemy.

Я подозреваю, что обе сессии не содержат ничего в начале запросов, которые теперь находятся в приведенном выше потоке кода одновременно.

requestA проходит через соответствующий поток кода и объединяет new_contact в sessionA.

В то же время requestB проходит через тот же путь кода, где контакт None (поскольку sessionA еще не зафиксирован) и объединяет new_contact в sessionB.

Then sessionA обязуется перед началом сессииB. Когда SessionB переходит к фиксации, он получает нарушение PK.

Можем ли мы сделать что-нибудь еще, кроме как поймать нарушение ПК и соответственно отреагировать?

ответ

0

У вас есть два варианта:

  1. Поймать запрещенный PK и реагировать соответствующим образом, как вы уже сказали.

  2. Заблокируйте транзакцию на основе вашего идентификатора: это сложнее, вам нужно что-то синхронизировать свои блокировки, например redis. Взгляните на python-redis-lock. Это всего лишь один из вариантов, решение здесь заключается в том, чтобы избежать параллелизма для ПК.

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

Смежные вопросы