1.實現事務的三種方式
1.1?全局開啟事務---> 全局開啟事務,綁定的是http請求響應整個過程
DATABASES = {'default': {#全局開啟事務,綁定的是http請求響應整個過程'ATOMIC_REQUESTS': True, }}
from django.db import transaction# 局部禁用事務
@transaction.non_atomic_requests
def seckill(request):return HttpResponse('秒殺成功')
?1.2 一個視圖函數在一個事物中
# fbv開啟from django.db import transaction@transaction.atomicdef seckill(request):return HttpResponse('秒殺成功')
# cbv開啟
from django.db import transaction
from rest_framework.views import APIView
class SeckillAPIView(APIView):@transaction.atomicdef post(self, request):pass
1.3 局部使用事務
from django.db import transaction
def seckill(request):with transaction.atomic(): #不用提交事務 with上下文管理器pass # 都在一個事物中return HttpResponse('秒殺成功')
2 事物的回滾和保存點
# 1 普通事務操作(手動操作)
transaction.atomic() # 開啟事務
transaction.commit() # 提交事務
transaction.rollback() # 回滾事務# 2 可以使用上下文管理器來控制(自動操作)
with transaction.atomic(): # 自動提交和回滾
保存點
在事務操作中,我們還會經常顯式地設置保存點(savepoint)
一旦發生異常或錯誤,我們使用savepoint_rollback方法讓程序回滾到指定的保存點
如果沒有問題,就使用savepoint_commit方法提交事務
from .models import Book
from django.db import transaction
def seckill(request):with transaction.atomic():# 設置回滾點,一定要開啟事務sid = transaction.savepoint()print(sid)try:book = Book.objects.get(pk=1)book.name = '紅樓夢'book.save()except Exception as e:# 如發生異常,回滾到指定地方transaction.savepoint_rollback(sid)print('出異常了,回滾')# 如果沒有異常,顯式地提交一次事務transaction.savepoint_commit(sid)return HttpResponse('秒殺成功')
transaction.atomic() # 開啟事務
sid = transaction.savepoint() # 設置保存點
transaction.savepoint_rollback(sid) # 回滾到保存點
transaction.savepoint_commit(sid) #提交保存點
3 事務提交后,執行某個回調函數
?有的時候我們希望當前事務提交后立即執行額外的任務,比如客戶下訂單后立即郵件通知賣家
?案例一
def send_email():print('發送郵件給賣家了')
def seckill(request):with transaction.atomic():# 設置回滾點,一定要開啟事務sid = transaction.savepoint()print(sid)try:book = Book.objects.get(pk=1)book.count = book.count-1book.save()except Exception as e:# 如發生異常,回滾到指定地方transaction.savepoint_rollback(sid)else:transaction.savepoint_commit(sid) #提交事務transaction.on_commit(send_email) #提交事務之后執行send_email函數return HttpResponse('秒殺成功')案例二
transaction.on_commit(lambda: send_sms.delay('1898288322'))
#異步提交,利用celery提交異步任務