首页 > 其他分享 >14. 事务

14. 事务

时间:2023-02-20 17:23:31浏览次数:27  
标签:事务 transaction 14 models create objects import age

2.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.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("...")

 

 

 

2.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("...")

 

标签:事务,transaction,14,models,create,objects,import,age
From: https://www.cnblogs.com/victor1234/p/17138202.html

相关文章