[英]django: commit and raise inside transaction.atomic()
我們正在嘗試從commit_manually
遷移到atomic
以便可以在舊項目中將Django至少升級到1.8。 在大多數情況下,我們需要執行以下操作:
with transaction.atomic():
obj = Entity.objects.select_for_update().get(pk=pk)
try:
obj.do_something()
obj.set_some_status()
obj.save()
except SomeException:
obj.set_failed_flag()
obj.save()
raise
因為被呼叫者需要此異常信息才能繼續執行特定流程。 但是在這種情況下,事務/保存點將回滾,這不是我們想要的,因為我們希望obj.set_failed_flag()
被提交。 將它設置在同一原子塊內似乎也是合乎邏輯的,因為我們已經為此對象設置了鎖定行。
有什么想法/模式嗎? 提前致謝!
PS:使用舊的手動交易管理是如此簡單!
PPS我們也對“提前退出”使用例外,並且將其移到一些標志等上會帶來混亂的日志,我個人很想避免這種情況。
假設SomeException
不是數據庫異常,您可以保存它並將其引發到原子塊之外:
with transaction.atomic():
obj = Entity.objects.select_for_update().get(pk=pk)
try:
obj.do_something()
obj.set_some_status()
except SomeException as e:
obj.set_failed_flag()
exception = e
else:
exception = None
obj.save()
if exception:
raise exception
如果您發現此操作過於冗長且需要經常執行,則可以編寫一個上下文管理器來充當transaction.atomic()
的代理,但在某些情況下不會觸發回滾。
最后,請注意,Django仍然具有手動事務管理功能 。
除了已經發布的答案外,如果您使用嵌套方法在原子鏈中更高位置處啟動原子塊,則可以使用以下方法:
transaction.on_commit(lambda: method_that_raises_exception())
這樣,在提交事務后會引發異常。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.