from django.db import transaction
transaction.atomic # 原子性操做,把一系列操做當作一個總體,錯了則集體回退 transaction.on_commit(func,using = None) # 在整個事件完成後,執行func函數
from django.db import transaction
# atomic @transaction.atomic def index(request): ... def index(request): with transation.atomic(): .... .... # on_commit @transaction.atomic def index(request): do_something... transation.oncommit(func)
from django.db import models class Account(models.Model): nid = models.IntegerField(primary_key=True) money = models.IntegerField(verbose_name="餘額")
from django.contrib import admin from django.urls import path,re_path,include from app01 import views urlpatterns = [ re_path("index.html",views.index) ]
一、正常狀況,轉帳成功html
from django.shortcuts import render,HttpResponse from app01 import models from django.db.models import F def index(request): models.Account.objects.filter(nid=1).update(money=F("money")-1) # 帳號1給帳號2轉帳1元錢 # raise IndexError models.Account.objects.filter(nid=2).update(money=F("money")+1) return HttpResponse("OK")
二、轉帳到一半出現錯誤django
from django.shortcuts import render,HttpResponse from app01 import models from django.db.models import F def index(request): models.Account.objects.filter(nid=1).update(money=F("money")-1) raise IndexError models.Account.objects.filter(nid=2).update(money=F("money")+1) return HttpResponse("OK")
三、還原全部money到1000,配置事務app
from django.shortcuts import render,HttpResponse from app01 import models from django.db import transaction from django.db.models import F def index(request): with transaction.atomic(): models.Account.objects.filter(nid=1).update(money=F("money")-1) raise IndexError models.Account.objects.filter(nid=2).update(money=F("money")+1) return HttpResponse("OK") # 能夠使用裝飾器 # @transaction.atomic # def index(request): # models.Account.objects.filter(nid=1).update(money=F("money")-1) # raise ValueError("出錯") # models.Account.objects.filter(nid=2).update(money=F("money")+1) # return HttpResponse("OK")
四、驗證on_commitide
說明:若是原子性操做出錯,則整個on_commit都不會執行,不管on_commit放在什麼位置。這與直接在該位置執行func是不同的。函數
from django.shortcuts import render,HttpResponse from app01 import models from django.db import transaction from django.db.models import F def before(): print("before") # 能夠作一些特定工做,如發郵件、記錄log def after(): print("after") @transaction.atomic def index(request): transaction.on_commit(before) models.Account.objects.filter(nid=1).update(money=F("money")-1) # raise ValueError("出錯") models.Account.objects.filter(nid=2).update(money=F("money")+1) transaction.on_commit(after) return HttpResponse("OK")
from django.shortcuts import render,HttpResponse from app01 import models from django.db import transaction from django.db.models import F def before(): print("before") # 能夠作一些特定工做,如發郵件、記錄log def after(): print("after") @transaction.atomic def index(request): transaction.on_commit(before) models.Account.objects.filter(nid=1).update(money=F("money")-1) raise ValueError("出錯") models.Account.objects.filter(nid=2).update(money=F("money")+1) transaction.on_commit(after) return HttpResponse("OK")