Django中的事务介绍

一、Django事务介绍

在Django中,它的 默事务行为是自动提交。除非事务正在执行,每个查询将会马上自动提交到数据库, 例如:

# ApiData为model
ApiData.objects.create(name='测试名字', path='/')
ApiData.objects.filter(id=1).update(name='测试名字', path='/')

如果没有手动设置事务,那么这两条代码在执行完成后就会马上提交到数据库中进行保存,Django 自动使用事务或还原点,以确保需多次查询的 ORM 操作的一致性,特别是 delete() 和 update() 操作。

二、使用Django事务

通过django手动创建事务的方式一般为两种:装饰器和with:

装饰器:

@api_view(['POST'])
@transaction.atomic
def test_views(request):
    """
    该方法会在一个事务中执行
    """
    ApiData.objects.create(name='测试名字', path='/')
    ApiData.objects.filter(id=1).update(name='测试名字', path='/')
    return Response(data={
    
    'msg': '创建成功!'})

with语句:

@api_view(['POST'])
def test_views(request):
    try:
        with transaction.atomic(): #仅with包裹的下面的语句会在事务中执行
            ApiData.objects.create(name='测试名字', path='/')
            ApiData.objects.filter(id=1).update(name='测试名字', path='/')
    except Exception as e:
        pass
    return Response(data={
    
    'msg': '创建成功!'})

需要注意的是当事务回滚时,模型的属性需要手动恢复。

例如下面的代码,obj.active的初始值是False.我们设置了obj.active=True然后进行了保存obj.save()操作,但这个时候发生了异常导致保存失败了,那此时的obj.active的值还是为True,并不会因为保存失败而变为False

from django.db import DatabaseError, transaction

obj = MyModel(active=False)
obj.active = True
try:
    with transaction.atomic():
        obj.save()
except DatabaseError:
    pass

if obj.active: #下面的代码
    ...

因此,针对上面的代码我们可以在抛异常处将active的值设为False来达到恢复模型属性的值的目的:

try:
    with transaction.atomic():
        obj.save()
except DatabaseError:
    obj.active=False #手动恢复active属性

三、全局事务

如果为了图省事而场景也较为通用,我们可以设置全局事务配置来让每个请求view都使用事务:
settings.py配置文件中增加下面配置:

ATOMIC_REQUESTS=True

这样就将每个视图包裹在这个数据库的事务中了,只有视图未完成执行成功,都将回滚到请求前的初始状态。


另外也可以增加AUTOCOMMIT=False的配置项来禁用Django的事务管理以此来使用自定义的事务。

猜你喜欢

转载自blog.csdn.net/momoda118/article/details/128177420
今日推荐