我有一個唯一的整數需要與問候的外鍵遞增模式,下面的代碼是我目前如何處理它:Django的 - 下拉列表AutoField至於外鍵
class MyModel(models.Model):
business = models.ForeignKey(Business)
number = models.PositiveIntegerField()
spam = models.CharField(max_length=255)
class Meta:
unique_together = (('number', 'business'),)
def save(self, *args, **kwargs):
if self.pk is None: # New instance's only
try:
highest_number = MyModel.objects.filter(business=self.business).order_by('-number').all()[0].number
self.number = highest_number + 1
except ObjectDoesNotExist: # First MyModel instance
self.number = 1
super(MyModel, self).save(*args, **kwargs)
我對本以下問題:
- 多的人可以創造
MyModel
實例爲同一business
,所有在互聯網上。是否有可能同時創建MyModel
實例的2個人,並且.count()
同時返回500個,然後都嘗試在同一時間基本上設置self.number = 501
(引發IntegrityError)?答案似乎是一個明顯的「是的,它可能發生」,但我不得不問。 - 有沒有一個捷徑,或者「最好的方式」來做到這一點,我可以使用(或者可以用
SuperAutoField
來處理這個問題)?
我不能只巴掌while model_not_saved:
try:
,except IntegrityError:
的,因爲模型中的其他限制可能會導致一個無限循環和災難切爾諾貝利相比更糟糕的(也許不是那麼糟糕)。
@保羅 - 謝謝。我不明白。我不知道事務會保證在事務處理期間讀取的任何行沒有變化,當然,保護部分失敗的提交階段也是如此。這是如此嗎?如果是這樣,我可以簡單地保存在'@ commit_on_success'中,否? – orokusaki 2010-10-21 20:59:12
@Paul - 似乎事務不會解決併發中發生的另一個破壞約束的'IntegrityError'問題,它可能與'number'引起的錯誤相混淆。 – orokusaki 2010-10-21 21:00:57
精確的交易行爲將取決於您使用的數據庫以及配置方式。如果啓用事務中間件並將隔離級別設置爲可重複讀取數據庫,則您的方法將按原樣工作。在這種情況下,這可能不會成爲性能問題,但可能會影響其他代碼。 – 2010-10-21 21:12:49