2015-04-06 4 views
1

Я использую django беспокойный для запроса POJ ajax, который занял почти 10-20 секунд.Несколько ajax-запросов (Singleton Pattern)

Вот мой код.

class testEndPoint(Endpoint): 
    def post(self, request): 
     testForm = TestEmailForm(request.data) 
     if testForm.is_valid(): 
      sometable = EmailTable.object.get(**condition) 
      if sometable.is_email_sent == false: 
       #Send Email 
       #Took around 15 seconds 
       sometable.is_email_sent = true 
       sometable.save() 
     else: 
      result = testForm.errors 
     return serialize(result) 

я зову его через $.ajax, но проблема в том, если два запроса ударил этот адрес с разницей миллисекунды времени, как запрос проходит через if sometable.is_email_sent = false: состояние.

Как предотвратить множественную подачу. Прямо сейчас я переехал sometable.is_email_sent = true;sometable.save(); перед отправкой электронной почты, но мне нужно больше общего решения, так как есть еще десятки мест, где это происходит. Я на Джанго 1.5

django restless

+0

Не в django и просто проходящий, но не можете ли вы установить $ .ajax для асинхронного ложного? – misha130

+0

Мне нужно решение на стороне сервера. –

+0

Синхронный ajax почти никогда не то, что вы хотите (вы можете закончить замораживание всего браузера в течение 15 секунд). – thebjorn

ответ

1

Вы должны отключить исходящий входной элемент, прежде чем начать свой AJAX вызов (что позволит предотвратить большинство этих вопросов).

оставшиеся проблемы могут быть решены с помощью select_for_update

class testEndPoint(Endpoint): 
    @transaction.commit_manually 
    def post(self, request): 
     testForm = TestEmailForm(request.data) 
     if testForm.is_valid(): 
      condition['is_email_sent'] = False 
      try: 
       rows = EmailTable.objects.select_for_update().filter(**condition) 
       for row in rows: 
        row.is_email_sent = True 
        row.save() 
        #Send Email 
      except: 
       transaction.rollback() 
       raise 
      else: 
       transaction.commit() 

     else: 
      result = testForm.errors 
     return serialize(result) 

select_for_update не будет блокировать строки до конца транзакции (то есть он должен быть внутри транзакции). Добавив is_email_sent=False к condition, мы можем удалить if. Я переместил изменение is_email_sent над «Отправить электронную почту», но это не является абсолютно необходимым - в любом случае он будет отменен при откате транзакции, если есть исключение.

+0

thats great, я на django 1.5, и нет транзакции.atomic –

+0

Я обновил ответ, чтобы использовать синтаксис 1.5. – thebjorn

+0

Я не проверял ваш код, но вы можете снова взглянуть на состояние. У меня здесь две проблемы: одна с одним и тем же пользователем, выполняющая несколько запросов, а другая - несколько пользователей, выполняющих один и тот же запрос одновременно. –