1局部事务(*)
from rest_framework.views import APIView
from rest_framework.response import Response
from django.db import transaction
from api import models
class Demo1View(APIView):
def get(self, request, *args, **kwargs):
try:
with transaction.atomic():
models.UserInfo.objects.create(name='v1', age=1)
models.Order.objects.create(name='v1', age=1)
except Exception as e:
print("异常,自动回滚")
return Response("...")
事务提交的回调函数(本质上就是事务完成后,自动执行一个函数):
from rest_framework.views import APIView from rest_framework.response import Response from django.db import transaction from api import models from functools import partial def db_success_callback(*args, **kwargs): print(args, **kwargs) class Demo1View(APIView): def get(self, request, *args, **kwargs): try: with transaction.atomic(): # 回调函数,事务正常提交自动执行 transaction.on_commit(db_success_callback) transaction.on_commit( partial(db_success_callback, 11, 22, 33) ) models.UserInfo.objects.create(name='v1', age=1) models.Order.objects.create(title='v1', count=1) except Exception as e: print("异常,自动回滚") # on_commit回调函数内部异常时不会回滚 return Response("...")
回滚到 指定事务点:
from rest_framework.views import APIView
from rest_framework.response import Response
from django.db import transaction
from api import models
class Demo1View(APIView):
def get(self, request, *args, **kwargs):
try:
with transaction.atomic():
# 回调函数,事务正常提交自动执行
n1 = transaction.savepoint()
models.UserInfo.objects.create(name='v1', age=1)
n2 = transaction.savepoint()
models.UserInfo.objects.create(name='v2', age=1)
# 必须在事务里面,回顾到指定 事务点,后续东西不提交
transaction.savepoint_rollback(n2)
except Exception as e:
print("异常,自动回滚", e) # on_commit回调函数内部异常时不会回滚
return Response("...")
2 视图事务
针对整个视图进行开启事务:
-
视图内,有数据库操作异常,自动回滚
-
视图内,有其他异常,不会回滚。
from rest_framework.views import APIView
from rest_framework.response import Response
from django.db import transaction, IntegrityError
from api import models
class Demo1View(APIView):
@transaction.atomic
def get(self, request, *args, **kwargs):
try:
models.UserInfo.objects.create(name='v100', age=1)
models.UserInfo.objects.create(name="v200", age="xxx") # 有异常,回滚,即:v100不会保存
int("asdf") # 有异常,不会滚,即:两条数据正常保存到数据库
except Exception as e:
pass
return Response("...")
定义事务点,自定义回滚位置:
from rest_framework.views import APIView
from rest_framework.response import Response
from django.db import transaction, IntegrityError
from api import models
class Demo1View(APIView):
@transaction.atomic
def get(self, request, *args, **kwargs):
try:
models.UserInfo.objects.create(name='v10', age=1)
n1 = transaction.savepoint()
models.UserInfo.objects.create(name="v11", age=1)
n2 = transaction.savepoint()
models.UserInfo.objects.create(name='v12', age=1)
n3 = transaction.savepoint()
models.UserInfo.objects.create(name='v13', age=1)
# 后续读取到某些值后,发现 v12不应该创建,那么就可以主动回滚
transaction.savepoint_rollback(n1)
except Exception as e:
print("有异常", e)
return Response("...")
3 全局事务
效率低:项目中一般不会使用。
如果想要开启全局事务,需要在连接数据库时多设置一个参数:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'dbhot4',
'USER': 'root',
'PASSWORD': 'root123',
'HOST': '127.0.0.1',
'PORT': '3306',
'ATOMIC_REQUESTS': True
}
}
-
只要视图函数执行异常,无论是什么原因触发,均自动回滚。
class Demo1View(APIView): def get(self, request, *args, **kwargs): models.UserInfo.objects.create(name='v1', age=1) models.UserInfo.objects.create(xxxxxxx='v2', age=1) # 错误 return Response("...") class Demo1View(APIView): def get(self, request, *args, **kwargs): models.UserInfo.objects.create(name='v1', age=1) models.UserInfo.objects.create(name='v2', age=1) int("asdf") # 错误 return Response("...") -
如果视图函数执行不报错(try处理异常,也叫不报错),则不会回滚
class Demo1View(APIView): def get(self, request, *args, **kwargs): try: models.UserInfo.objects.create(name='v1', age=1) models.UserInfo.objects.create(xxxxxxx='v2', age=1) int("xxx") except Exception as e: pass return Response("...") # 视图函数执行没有报错,不会滚回。
如果开启了全局事务,想要免除某个指定的函数不需要开启事务,则可以使用:
from rest_framework.views import APIView
from rest_framework.response import Response
from django.db import transaction, IntegrityError
from api import models
from django.utils.decorators import method_decorator
@method_decorator(transaction.non_atomic_requests, name='dispatch')
class Demo1View(APIView):
def get(self, request, *args, **kwargs):
models.UserInfo.objects.create(name='v100', age=1)
models.UserInfo.objects.create(name="v200", age="xxx") # 报错
return Response("...")
浙公网安备 33010602011771号