我正在使用Django 1.3开发一个Web应用程序,我有一个看起来像这样的处理程序:
@transaction.commit_manually
@login_required(redirect_field_name='')
def problematic_handler(request):
try:
my_record = models.MyRecords.objects.get(...)
# lots of database operations based on my_record
my_record.delete()
transaction.commit()
return ...
except:
transaction.rollback()
return ...
我的问题是,在第一次调用甚至返回之前,用户可以多次调用problematic_handler(),这将产生比所需更多的数据库记录。
不幸的是,PRG模式在这里没有帮助:/
有没有什么方法可以限制用户在等待第一次调用返回时调用处理程序两次? 或者是否可以在第二次调用处理程序时生成异常? (假设第一个尚未完成的来源)
答案 0 :(得分:0)
我建议您尝试在事务中执行QuerySet.select_for_update
,该事务应在事务期间锁定已检索的my_record
实例。这将禁用对problematic_handler
的连续调用以获得额外的锁定,并且在尝试中将引发django.db.DatabaseError
异常,您可以在其中设计适当的验尸程序。
对于1.4之前的Django版本,如果您的数据库支持,我建议您尝试为数据库记录执行raw SQL select for update query。否则,您需要在应用程序级别和ymmv上实现锁定,以防您的应用程序在多进程上下文中运行。