Django"死锁发现"与transaction.atomic

时间:2018-05-07 19:38:27

标签: django python-3.x django-models atomic

我有一个更新模型的函数,或者如果它不存在则创建一个新条目:

<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<form name="searchTraining">
  <div class="ui-widget">
    <label for="search">Search: </label>
    <textarea class="tradeF" name='trade' id='trade' placeholder="Trade" autocomplete="on" pattern="[a-zA-Z ]+" size="21"></textarea>
  </div>
  <input pattern="[0-9]+" placeholder="Training ID" name="trainingID" size="1" class="idF" type="text" title="TrainingID">
  <input autocomplete="on" pattern="[0-9]+" placeholder="Total" name="totalParticipants" size="3" type="text" class="totalF">
  <input autocomplete="on" pattern="[0-9]+" placeholder="Male" name="male" size="3" type="text" class="maleF">
  <input autocomplete="on" pattern="[0-9]+" placeholder="Female" name="female" size="3" type="text" class="femaleF">
  <input autocomplete="on" pattern="[a-zA-Z ]+" placeholder="District" name="district" size="3" type="text">
  <input autocomplete="on" pattern="[a-zA-Z ]+" placeholder="Project" name="project" size="3" type="text" value="kfw"> From
  <input name="fromDate" size="3" type="text"><br />To<input name="toDate" size="3" type="text">
  <input autocomplete="on" pattern="[a-zA-Z ]+" placeholder="Venue" name="venue" size="3" type="text">
  <input autocomplete="on" pattern="[a-zA-Z ]+" placeholder="Resource Person" name="rPerson" size="3" type="text">
  <input type="hidden" name="defaulter" value="true" />
  <input type="hidden" name="questItem" value="" />
</form>

在特定情况下,这个函数被调用两次以至于它在数据库上创建了两个条目,因此,我包含了一个唯一的约束来确保它不会发生。

但后来我开始收到此错误:

try:            
  obj=model.objects.get(id=id)
  setattr(obj, 'completed', True)
  obj.save()
except:
  model.objects.create(id=x, user=y, completed=True)

所以我尝试使用锁定:

Duplicate entry '1-13' for key 'x_y_z_uniq'

但现在提出这个错误:

with transaction.atomic():
  try:            
    obj=model.objects.select_for_update().get(id=id)
    setattr(obj, 'completed', True)
    obj.save()
  except:
    model.objects.create(id=x, user=y, completed=True)

我想要一种方法,即函数的第一次调用将创建一个新条目,第二次调用将更新该条目,但第二次调用因为死锁而失败,我怎样才能使第二次调用等待第一个完成?

1 个答案:

答案 0 :(得分:0)

对我来说,你可以在这里使用简单的.update()方法:
obj=model.objects.filter(id=id).update(completed=True)

更重要的是,您可以将所有代码重构为Importing and exporting blocks

obj, created = model.objects.update_or_create(
    id=id,
    defaults={'id': x, 'user': y, 'completed': True}
)