【发布时间】:2023-03-24 20:50:01
【问题描述】:
我有一堆视图,我在执行之前检查某些条件是否为真。首先执行哪个视图并不重要,但我担心一个用户使用的视图会在另一个视图中检查条件后更改数据。非常感谢您对此的任何帮助。
我正在使用设置 ATOMIC_REQUESTS = True 的 2 勺建议,将每个请求包装在事务中。我的网站流量相对较低,所以我还不关心性能。也使用 postgres。
def feed_dog(self, dog_id):
dog = get_objects_or_404(Dog, pk=dog_id)
if not dog.removed and not dog.fed_today: # line 3
# do additional checks
dog.fed_today = True # line 5
dog.save()
# also modify other related objects
treat = Treats.objects.last()
treat.dogs_being_fed_with_this_treat.add(dog)
treat.save()
def remove_dog_from_feed_list(self, dog_id):
dog = get_objects_or_404(Dog, pk=dog_id)
if not dog.fed_today # line 12
dog.removed = True
dog.save()
treat.dogs_being_fed_with_this_treat.remove(dog)
treat.save()
所以我担心有人调用了 feed_dog 视图,然后在检查了第 3 行之后但在第 5 行开始之前,另一个用户调用了 remove_dog 函数。由于当用户 2 调用 remove_dog 时 dog.fed_today 仍然为 False,第 12 行为 True,并且 remove_dog 视图继续执行 dog.removed = True。同时,feed_dog 视图继续并设置 dog.fed_today=True,将狗添加到 Treat 数组等。所以我有不一致的状态 dog.removed = True 和 dog.fed_today = True。
基本上我需要它,以便 Dog 模型上的某些属性不能同时为 True,例如 dog.fed_today =True 和 dog.removed=True。我也有这个相关的模型 Treat,我不希望 dog 对象被删除 = True 并且也在treat.dogs_being_fed 数组中。
问:这是一个有效的担忧吗?既然事务提供了隔离,这是否意味着其中一个视图在另一个视图之前或之后访问数据(它们看不到半完成状态的数据)?
问:增加 Django/Postgres 与 Read Committed 的隔离属性是否有帮助?
问:对 Dog 模型本身进行约束是否会有所帮助(例如使用 def clean 方法表示 Dog 不能同时删除=True 和 fed_today = True?)。我主要检查视图中的内容。这会反映在交易中吗?我是否也可以创建一个反映多个模型中的属性的约束,例如不能有 dog.removed=True 并且让那只狗在 Treats.dogs_being_fed 数组中?
问:select_for_update 的目的是什么,它在这里有帮助吗?如果事务已经应该提供隔离,那么 select_for_update 的目的是什么?
感谢任何帮助!
【问题讨论】:
标签: django transactions django-views