Django中的事务ATOMIC_REQUESTS

 更新时间:2023年08月24日 16:11:52   作者:蓝绿色~菠菜  
这篇文章主要介绍了Django中的事务ATOMIC_REQUESTS使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

Django事务ATOMIC_REQUESTS

Django的默认事务行为

Django 的默认行为是以自动提交模式运行。

除非事务处于活动状态,否则每个查询都会立即提交到数据库。

将事务绑定到HTTP请求

在 Web 上处理事务的常用方法是将每个请求包装在事务中。

在要为其启用此行为的每个数据库的配置中设置ATOMIC_REQUESTS为True。

DATABASES = {
        'default': {
			'ENGINE': 'django.db.backends.mysql',
        	'NAME': 'testdb',
        	'USER': 'hayley',
        	'PASSWORD': '******',
        	'HOST': 'localhost',
        	'PORT': '3306',
            'ATOMIC_REQUESTS': True,
        }
    }

它是这样工作的:在调用视图函数之前,Django 会启动一个事务。如果生成的响应没有问题,则 Django 提交事务。如果视图产生异常,Django 会回滚事务。

您可以使用视图代码中的保存点执行子事务,通常使用atomic()上下文管理器。但是,在视图结束时,将提交所有更改或不提交任何更改。

虽然每个请求都开启事务比较方便,但它也会在流量增加时变得低效。为每个视图打开一个事务有一些开销。对性能的影响取决于应用程序的查询模式以及数据库处理锁定的能力。

以上是全局性的配置, 如果要对某个http请求放水(然后自定义事务),可以用non_atomic_requests修饰器

from django.db import transaction
class xxx(xxxView):
    @transaction.non_atomic_requests
    def post(self, request, *args, **kwargs):
        ...
 

或者关闭全局事务,为每个请求单独设置事务:

 
from django.db import transaction
class xxx(xxxView):
    @transaction.atomic
    def post(self, request, *args, **kwargs):
        with transaction.atomic():
            ...
 

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的事务管理以此来使用自定义的事务。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • python进行文件对比的方法

    python进行文件对比的方法

    在本篇内容里小编给分享了关于python进行文件对比的方法和步骤,需要的朋友们可以学习下。
    2018-12-12
  • python分布式爬虫中消息队列知识点详解

    python分布式爬虫中消息队列知识点详解

    在本篇文章里小编给大家整理的是python分布式爬虫中消息队列知识点详解内容,有兴趣的朋友们可以参考下。
    2020-11-11
  • 使用pth文件添加Python环境变量方式

    使用pth文件添加Python环境变量方式

    这篇文章主要介绍了使用pth文件添加Python环境变量方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-05-05
  • python实现将汉字转换成汉语拼音的库

    python实现将汉字转换成汉语拼音的库

    这篇文章主要介绍了python实现将汉字转换成汉语拼音的库,涉及Python调用word.data字段实现将汉字转换成拼音的功能,非常具有实用价值,需要的朋友可以参考下
    2015-05-05
  • pyinstaller执行报错的问题解决

    pyinstaller执行报错的问题解决

    有时候,PyInstaller可能无法正确识别和打包所有的依赖项,导致名称错误,本文主要介绍了pyinstaller执行报错的解决方案,感兴趣的可以了解一下
    2023-11-11
  • pandas计算相关系数corr返回空的问题解决

    pandas计算相关系数corr返回空的问题解决

    本文主要介绍了pandas计算相关系数corr返回空的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-01-01
  • Python字符串对齐、删除字符串不需要的内容以及格式化打印字符

    Python字符串对齐、删除字符串不需要的内容以及格式化打印字符

    这篇文章主要给大家介绍了关于Python字符串对齐、删除字符串不需要的内容以及格式化打印字符的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • Python实现提取和去除数据中包含关键词的行

    Python实现提取和去除数据中包含关键词的行

    这篇文章主要介绍了Python如何提取数据中包含关键词的行已经如何去除数据中包含关键词的行,文中的示例代码讲解详细,需要的可以参考一下
    2023-08-08
  • widows下安装pycurl并利用pycurl请求https地址的方法

    widows下安装pycurl并利用pycurl请求https地址的方法

    今天小编就为大家分享一篇widows下安装pycurl并利用pycurl请求https地址的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-10-10
  • Python使用PyMuPDF实现添加PDF水印

    Python使用PyMuPDF实现添加PDF水印

    在日常工作中,我们经常需要对PDF文件进行处理,其中一项常见的需求是向PDF文件添加水印,本文将介绍如何使用Python编程语言和PyMuPDF库在PDF文件中添加水印,感兴趣的可以了解一下
    2023-08-08

最新评论