假设我有一个具有唯一字段电子邮件的模型:
class MyModel:
email = models.EmailField(unique=True)
def save(self):
.... # save model
def clean(self):
.... # validate model, make sure email doesn't already exist.
通常,如果浏览器提交一个表单,其中 email 是一个已经存在的值,由于模型表单字段验证,它会引发 ValidationError。
如果两个浏览器同时提交相同的电子邮件,其中电子邮件是一个尚不存在的值,则至少有一个请求将通过将一行保存到数据库中而成功。另一个请求,如果它在第一个请求之后到达足够长的时间,将被正常处理 - 引发 ValidationError 表示电子邮件已经存在。但是,如果它几乎与第一个请求同时到达,那么clean()
将成功 - 电子邮件还不存在,但在save()
执行该方法时,来自第一个请求的行将被保存。在后一种情况下,将引发 IntegrityError,并且服务器将返回内部服务器 500 错误,这是不可取的。
如何防止最后一种情况发生?数据库事务?