概要
Transaction是django進(jìn)行數(shù)據(jù)庫(kù)原子性操作在python層面上的實(shí)現(xiàn)。
簡(jiǎn)單來(lái)說(shuō), 被transaction.atomic()包裹的代碼塊只在代碼塊順利完成后進(jìn)行數(shù)據(jù)庫(kù)層面的commit。實(shí)際開(kāi)發(fā)當(dāng)中,遇到了一些問(wèn)題。
1. transaction事務(wù)內(nèi)不執(zhí)行數(shù)據(jù)庫(kù)的commit操作
除非手動(dòng)commit
transaction最基本的功能。
代碼場(chǎng)景:
在事務(wù)當(dāng)前啟動(dòng)celery異步任務(wù), 無(wú)法獲取未提交的改動(dòng)。
def example_view(request):
with transaction.atomic():
change_obj() # 修改對(duì)象變量
obj.save()
async_task.delay(obj.id)
def async_task(obj_id):
obj = Model.objects.get(pk=obj_id)
read_the_obj() # 讀取對(duì)象信息
在使用transaction當(dāng)中, Model.save()都不做commit,因此如果在transaction當(dāng)中設(shè)置異步任務(wù),使用get()查詢(xún)數(shù)據(jù)庫(kù),將看不到對(duì)象在事務(wù)當(dāng)中的改變.這也是實(shí)現(xiàn)”可重復(fù)讀”的事務(wù)隔離級(jí)別,即同一個(gè)事務(wù)里面的多次查詢(xún)都應(yīng)該保持結(jié)果不變。
2.transaction只對(duì)數(shù)據(jù)庫(kù)層的操作進(jìn)行事務(wù)管理
不能理解為python操作的事務(wù)管理
代碼如下:
def example_view(request):
tag = False
with transaction.atomic():
tag = True
change_obj() # 修改對(duì)象變量
obj.save()
raise DataError
print("tag = ",tag)
即使事務(wù)代碼塊發(fā)生了DataError,事務(wù)回滾,也僅是數(shù)據(jù)庫(kù)層面的回滾,針對(duì)python的操作依然已完成。
甚至是對(duì)Model.Object進(jìn)行的操作會(huì)也會(huì)存在變量當(dāng)中。
如:
def example_view(request):
obj.changed = False
with transaction.atomic():
obj.changed = True
change_obj() # 修改對(duì)象其他變量
obj.save()
raise DataError
print("obj.changed = ",obj.changed)
obj.changed = True #輸出內(nèi)容
發(fā)生Dataerror異常的回滾僅在數(shù)據(jù)庫(kù)層面操作,因此不可以根據(jù)model object的屬性值判斷是否正確完成了事務(wù)。
另外,雖然Django對(duì)數(shù)據(jù)庫(kù)層面以O(shè)RM完成了很具體的抽象,但應(yīng)該要清楚地意識(shí)到我們操作的model object和數(shù)據(jù)庫(kù)內(nèi)容本質(zhì)不同,DJANGO只在查詢(xún)和提交時(shí)進(jìn)行數(shù)據(jù)庫(kù)操作。
補(bǔ)充:Django 事務(wù)transaction.atomic()的使用方法
看代碼吧~
from django.shortcuts import render
from django.http import HttpResponse
from django.views.generic import View
from django.db import transaction # 導(dǎo)入事務(wù)
# 類(lèi)視圖 (事務(wù),@transaction.atomic裝飾器)
class MyView(View):
@transaction.atomic
# transaction.atomic裝飾器可以保證該函數(shù)中所有的數(shù)據(jù)庫(kù)操作都在一個(gè)事務(wù)中。
def post(self, request):
# 數(shù)據(jù)庫(kù)操作1。。。
# 數(shù)據(jù)庫(kù)操作2。。。
return HttpResponse('ok')
# 類(lèi)視圖 (事務(wù),保存點(diǎn)的使用)
class MyView2(View):
@transaction.atomic
def post(self, request):
# 設(shè)置事務(wù)保存點(diǎn)
s1 = transaction.savepoint() # 可以設(shè)置多個(gè)保存點(diǎn)
# 數(shù)據(jù)庫(kù)操作。。。
# 事務(wù)回滾 (如果發(fā)生異常,就回滾事務(wù))
transaction.savepoint_rollback(s1) # 可以回滾到指定的保存點(diǎn)
# 提交事務(wù) (如果沒(méi)有異常,就提交事務(wù))
transaction.savepoint_commit(s1)
# 返回應(yīng)答
return HttpResponse('ok')
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。
您可能感興趣的文章:- python django事務(wù)transaction源碼分析詳解
- Django bulk_create()、update()與數(shù)據(jù)庫(kù)事務(wù)的效率對(duì)比分析
- django中使用事務(wù)及接入支付寶支付功能
- Django框架orM與自定義SQL語(yǔ)句混合事務(wù)控制操作
- django框架事務(wù)處理小結(jié)【ORM 事務(wù)及raw sql,customize sql 事務(wù)處理】
- 使用Python的Django框架實(shí)現(xiàn)事務(wù)交易管理的教程