Django 开启事务

一. django 开启事务

1. 方式一(局部使用)

1.1上下文管理

自动提交和回滚: with transaction.atomic():

from django.db import transaction
from django.http import HttpResponse
from .models import Book

def seckill(request):
    with transaction.atomic():
        # 设置回滚点,一定要开启事务
        sid = transaction.savepoint()

        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('秒杀成功')

1.2 普通操作

开启事务: transaction.atomic()
设置保存点: sid = transaction.savepoint()
提交事务(提交保存点): transaction.commit(sid)
回滚事务(回滚到保存点): transaction.rollback(sid)

from .models import Book
from django.db import transaction


def seckill(request):

    # 设置回滚点,一定要开启事务
    sid = transaction.savepoint()

    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('秒杀成功')

2.方式二(视图开启使用)

2.1 fbv

from django.db import transaction
@transaction.atomic
def seckill(request):
    return HttpResponse('秒杀成功')

2.2 cbv

from django.db import transaction
from rest_framework.views import APIView
class SeckillAPIView(APIView):
    @transaction.atomic
    def post(self, request):
        pass

方式三(全局使用)

# 全局,每次请求在一个事务中,粒度太大,事务时间很长
DATABASES = {
 'default': {
     'ENGINE': 'django.db.backends.mysql',
     'NAME': 'lqz',
     'HOST': '127.0.0.1',
     'PORT': '3306',
     'USER': 'lqz',
     'PASSWORD': 'lqz123',

      #全局开启事务,绑定的是http请求响应整个过程
     'ATOMIC_REQUESTS': True,
     }
}


# 局部禁用全局事务
from django.db import transaction
# 局部禁用事务
@transaction.non_atomic_requests
def seckill(request):
    return HttpResponse('秒杀成功')


# 多数据库,用default的视图不受事务控制
@transaction.non_atomic_requests(using='default')
def seckill(request):
    return HttpResponse('秒杀成功')

二. 查看内部SQL语句

方式一:

res_list = models.User.objects.values_list('name', 'age')
# 返回的数据格式为列表套元祖 - 本质上是一个 QuerySet 对象 ,而不是真的列表
print(res_list)  # <QuerySet [('xiaomeng', 18)]>
# 该语句可以查看当前执行命令的 SQL 语句 - 只有queryset对象才能使用该方法
print(res_list.query)  # SELECT `app01_user`.`name`, `app01_user`.`age` FROM `app01_user`

方式二:

(1) 所有 SQL语句 都可以使用

(2) 在项目的`settings.py`文件中增加默认配置

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console':{
            'level':'DEBUG',
            'class':'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'propagate': True,
            'level':'DEBUG',
        },
    }
}
posted @ 2024-03-26 21:14  codegjj  阅读(30)  评论(0)    收藏  举报