2013-10-25 4 views
3

У меня есть система комментариев с потоком, которая работает отлично 99,9% времени, но очень редко дерево разбивается, а значения влево/вправо дублируются.django-mptt: работа с параллельными вставками

Я обнаружил, что это происходит, когда два сообщения происходят одновременно (в течение секунды друг от друга), и, по-видимому, происходит то, что второе сообщение обновляет значения слева/справа дерева до первого завершил это.

Мой комментарий вставить код из views.py является следующее:

@login_required 
@transaction.autocommit 
def comment(request, post_id): 
    parent = get_object_or_404(Post, pk=post_id) 

    if request.method == 'POST': 
     form = PostForm(request.POST) 

     form.parent = post_id 
     if form.is_valid(): 
      new_post = newPost(request.user, form.cleaned_data['subject'], form.cleaned_data['body']) 
      new_post.insert_at(parent, 'last-child', save=True) 
      return HttpResponseRedirect('/posts/') 
    else: 
     form = PostForm() 

    return render_to_response('posts/reply.html', {'requestPost': request.POST, 'form': form, 'parent': parent}, context_instance=RequestContext(request)) 

Что такое правильный подход к решению этого? Есть ли способ django для обеспечения того, чтобы второе представление не вызывалось до завершения первой транзакции базы данных? Или мне нужно перестроить дерево после каждой вставки, чтобы обеспечить целостность? Или есть лучший способ вставки, который нужно использовать?

Спасибо!

Редактировать: Я использую MySQL.

+0

Вы нашли решение или лучше сказать обходной путь? – Daviddd

+0

Я перешел на новый (более быстрый) хост и обновил django-mptt в процессе, и проблема исчезла - возможно, только из-за того, что обновления db работают быстрее (так что шансы на параллелизм значительно сокращаются), а не на фактическую решающую проблему , – meepmeep

ответ

1

transaction.autocommit() является стандартным поведением джанго. Вы, декоратор, ничего не предпринимаете, если глобальное поведение транзакции не переопределено. Использование должно использовать commit_on_success() декоратор. Все операции с db будут отображаться в одной транзакции. Вы можете прочитать больше на https://docs.djangoproject.com/en/1.5/topics/db/transactions/

PS: В django 1.6 управление транзакциями будет обновлено, будьте внимательны.

+0

спасибо, но это предотвращает одновременное принятие других транзакций базы данных (называемых другими сеансами)? В основном я стараюсь, чтобы транзакции от разных пользователей были поставлены в очередь, чтобы второй не читал неправильные значения влево/вправо до завершения первой транзакции. – meepmeep

+0

Существует https://docs.djangoproject.com/en/1.5/ref/models/querysets/#select-for-update Он может блокировать записи, но я не знаю, как его использовать в коде django-mptt , – Hellpain