django 上的原子事务 queryset.update(**kwargs)
Atomic transaction on django queryset.update(**kwargs)
Django
的 queryset.update
方法似乎在 transaction.atomic
上下文管理器下执行。在 update
期间,我什么时候需要在我的代码中明确地执行此操作?或者这样做有什么好处,或者不这样做会有什么问题?
代码
try:
queryset = Model.objects.filter(a=1)
if queryset.count():
with transaction.atomic():
queryset.update(a=2) # queryset will [] after this.
for item in queryset:
item.emit_event('Updated')
except:
logger.info('Exception')
我的问题是我真的需要 transaction.atomic():
吗?
其次,在 .update
之后,我的查询集变空了,因为它是经过过滤的查询集。当我想在单个对象上发出事件时如何保留我的值。
第一
作为docs状态
Atomicity is the defining property of database transactions. atomic allows us to create a block of code within which the atomicity on the database is guaranteed. If the block of code is successfully completed, the changes are committed to the database. If there is an exception, the changes are rolled back.
在您的示例中,如果 emit_event
正在做某事,您将需要 atomic
,并且您希望仅当所有 emit_event
函数调用和 queryset.update
都完成时才完成此更新成功。但是,如果 emit_event
的状态不影响您更新的业务逻辑,那么这里的 atomic
将是多余的,因为正如您自己所说 update
具有内部 atomic
.
第二
查询集是惰性的。这意味着查询集的评估将在您对其进行迭代时完成。所以你需要做这样的事情。回复最新评论
try:
queryset = Model.objects.filter(a=1)
item_ids = list(queryset.values_list('id', flat=True)) # store ids for later
if item_ids: # optimzing here instead of queryset.count() so there won't be hit to DB
with transaction.atomic():
queryset.update(a=2) # queryset will [] after this.
for item in Model.objects.filter(id__in=item_ids): # <- new queryset which gets only updated objects
item.emit_event('Updated')
except:
logger.info('Exception')
看到那里我们在迭代它以获取更新的项目时创建了新的查询集
Django
的 queryset.update
方法似乎在 transaction.atomic
上下文管理器下执行。在 update
期间,我什么时候需要在我的代码中明确地执行此操作?或者这样做有什么好处,或者不这样做会有什么问题?
代码
try:
queryset = Model.objects.filter(a=1)
if queryset.count():
with transaction.atomic():
queryset.update(a=2) # queryset will [] after this.
for item in queryset:
item.emit_event('Updated')
except:
logger.info('Exception')
我的问题是我真的需要 transaction.atomic():
吗?
其次,在 .update
之后,我的查询集变空了,因为它是经过过滤的查询集。当我想在单个对象上发出事件时如何保留我的值。
第一
作为docs状态
Atomicity is the defining property of database transactions. atomic allows us to create a block of code within which the atomicity on the database is guaranteed. If the block of code is successfully completed, the changes are committed to the database. If there is an exception, the changes are rolled back.
在您的示例中,如果 emit_event
正在做某事,您将需要 atomic
,并且您希望仅当所有 emit_event
函数调用和 queryset.update
都完成时才完成此更新成功。但是,如果 emit_event
的状态不影响您更新的业务逻辑,那么这里的 atomic
将是多余的,因为正如您自己所说 update
具有内部 atomic
.
第二
查询集是惰性的。这意味着查询集的评估将在您对其进行迭代时完成。所以你需要做这样的事情。回复最新评论
try:
queryset = Model.objects.filter(a=1)
item_ids = list(queryset.values_list('id', flat=True)) # store ids for later
if item_ids: # optimzing here instead of queryset.count() so there won't be hit to DB
with transaction.atomic():
queryset.update(a=2) # queryset will [] after this.
for item in Model.objects.filter(id__in=item_ids): # <- new queryset which gets only updated objects
item.emit_event('Updated')
except:
logger.info('Exception')
看到那里我们在迭代它以获取更新的项目时创建了新的查询集