函数 transaction.atomic

数据库的读写操作中,事务在保证数据的安全性和一致性方面起着关键的作用,而回滚正是这里面的核心操作。

遇到并发的时候常常会因为接口的访问顺序或者其他情况,导致数据的不一致,这时候就知道回滚的重要性了,下面有个简单的小例子 可以实现数据库事务的操作

Demo

数据库的模型和返回值窝这边就不贴出来了

这是一个接口

from django.db import transaction
import time
def keke_test(request):
code = 1
msg = '操作成功' g = request.REQUEST.post
params = dict()
model_id = g.get('id', '0')
model = None
if model_id > 0:
model = IosSdkVersions.objects.filter(id=model_id).first()
with transaction.atomic(): # 禁止自动提交,保证该函数中的所有数据库操作在同一个事物中,第一个数据库操作1即使成功保存到数据库中,只要第2个数据操作失败,那么所有该段代码所有设计的都会更改回滚到原来
try:
sdk_flag_model = IosSdkTest.objects.filter(id=1).first()
sid = transaction.savepoint() # 开启事务设置事务保存点
sdk_flag_model.sdk_flag = 8
sdk_flag_model.save() # 完成就保存,但不是马上提交
time.sleep(10)
all_issue_field_value = IosSdkVersions.objects.filter(id=3)
for issue in all_issue_field_value:
issue.test_id = 8
issue.save()
# 1 / 0
except Exception as e:
print(e)
transaction.savepoint_rollback(sid) # 失败回滚事务(如果数据库操作发生异常,回滚到设置的事务保存点)
print('数据保存失败')
code = -1001
else:
code = 1
transaction.savepoint_commit(sid) # 如果没有异常,成功提交事物 params['code'] = code
return json_response(params) # 接口2,当执行第一个接口的时候,因为sleep的存在,这个操作会一直等待到第一个接口完成操作 再进行操作
def keke_test2(request):
code = 1
msg = '操作成功'
_g = request.REQUEST.get
sdk_flag_model = IosSdkTest.objects.filter(id=1).first()
sdk_flag_model.sdk_flag = 2
sdk_flag_model.save() # 因为被锁住了所以接口会等到上一个接口的完成
# if sdk_flag_model.sdk_flag == 8:
# all_issue_field_value = IosSdkVersions.objects.filter(id=3)
# for issue in all_issue_field_value:
# issue.test_id -= 2
# issue.save()
params = dict()
return json_response(params) # 接口2 other
def keke_test2(request):
code = 1
msg = '操作成功'
_g = request.REQUEST.get
sdk_flag_model = IosSdkTest.objects.filter(id=1).first()
if not sdk_flag_model.sdk_flag == 2: # 会等到flag为2的时候才去执行下面的操作
sdk_flag_model.sdk_flag = 3
sdk_flag_model.save()
params = dict()
params['code'] = code
return json_response(params) # other def keke_test2(request):
code = 1
msg = '操作成功'
_g = request.REQUEST.get
with transaction.atomic(): # 禁止自动提交,保证该函数中的所有数据库操作在同一个事物中,第一个数据库操作1即使成功保存到数据库中,只要第2个数据操作失败,那么所有该段代码所有设计的都会更改回滚到原来
sid = transaction.savepoint() # 开启事务设置事务保存点
try:
sdk_flag_model = IosSdkTest.objects.select_for_update().get(id=1) # 互扯锁的另一种实现
sdk_flag_model.sdk_flag = 8
sdk_flag_model.save()
time.sleep(10)
except Exception as e:
print(e)
transaction.savepoint_rollback(sid) # 失败回滚事务(如果数据库操作发生异常,回滚到设置的事务保存点)
print('数据保存失败')
code = -1001
else:
code = 1
transaction.savepoint_commit(sid) # 如果没有异常,成功提交事物
params = dict()
params['code'] = code
return json_response(params)

悲观锁

# 悲观锁实现, 都要放在 with transaction.atomic() 事务中 同条数据上锁完,需要等释放后才能再次上锁的吧

def keke_test2(request):
code = 1
msg = '操作成功'
_g = request.REQUEST.get
with transaction.atomic(): # 禁止自动提交,保证该函数中的所有数据库操作在同一个事物中,第一个数据库操作1即使成功保存到数据库中,只要第2个数据操作失败,那么所有该段代码所有设计的都会更改回滚到原来
sid = transaction.savepoint() # 开启事务设置事务保存点
try:
sdk_flag_model = IosSdkTest.objects.select_for_update().get(id=1) # 互扯锁的另一种实现
sdk_flag_model.sdk_flag = 8
sdk_flag_model.save()
time.sleep(10)
except Exception as e:
print(e)
transaction.savepoint_rollback(sid) # 失败回滚事务(如果数据库操作发生异常,回滚到设置的事务保存点)
print('数据保存失败')
code = -1001
else:
code = 1
transaction.savepoint_commit(sid) # 如果没有异常,成功提交事物
params = dict()
params['code'] = code
return json_response(params) def keke_test3(request):
code = 1
msg = '操作成功'
_g = request.REQUEST.get
with transaction.atomic():
sdk_flag_model = IosSdkTest.objects.select_for_update().get(id=1)
print(sdk_flag_model.sdk_flag)
params = dict()
params['code'] = code
return json_response(params)

原生sql 锁的操作

参考:https://segon.cn/mysql-for-update.html

Django transaction.atomic 事务的使用的更多相关文章

  1. Python Django,事务,transaction.atomic,事务保存点

    from django.shortcuts import renderfrom django.http import HttpResponsefrom django.views.generic imp ...

  2. Django中的事务(Transaction)管理

    Django默认的事务行为 默认情况下,在Django中事务是自动提交的.当我们运行Django内置的模板修改函数时,例如调用model.save()或model.delete()时,事务将被立即提交 ...

  3. Django中关于事务的代码编写

    Django中对于数据库的事务,默认每执行一句数据库操作,便会自动提交. 在Django中可以通过django.db.transaction模块提供的atomic来定义一个事务,atomic提供两种用 ...

  4. Django transaction 误用之后遇到的一个问题与解决方法

    今天在调试项目开发好的一个模块的时候,发现了一个很诡异的现象,最后追踪发现是因为在项目中事务处理有误所致.这个问题坑了我好一会,所以记录一下,以免再踩坑.下面开始详述. 我们都知道 Django 框架 ...

  5. django中使用事务以及接入支付宝支付功能

    之前一直想记录一下在项目中使用到的事务以及支付宝支付功能,自己一直犯懒没有完,趁今天有点兴致,在这记录一下. 商城项目必备的就是支付订单的功能,所以就会涉及到订单的保存以及支付接口的引入.先来看看订单 ...

  6. DJango中开启事务的两种方式

    目录 Django中开启事务的两种方式 第一种 第二种 Django中开启事务的两种方式 第一种 from django.db import transaction with transaction. ...

  7. 事务的隔离级别,mysql中开启事务、django中开启事务

    目录 一.事务的特性 二.数据库中开启事务 三.Django中开启事务的两种方式 第一种 第二种 四.事务的隔离级别 隔离级别 如何查看mysql隔离级别? 修改事务的隔离级别 隔离级别解释 read ...

  8. Django中MySQL事务的使用

    Django中事物的使用 from django.db import transaction @transaction.atomic通过transaction的@transaction.atomic装 ...

  9. Django中的事务与ajax

    一 事务与锁 1.行级锁 行级锁是由存储引擎实现的.如mysql里默认指定的InnoDB存储引擎,由它实现行级锁.InnoDB的行级锁定同样分为两种类型,共享锁(X)和排他锁(S). 对于UPDATE ...

  10. day54:django:锁和事务&Ajax&中间件Middleware

    目录 1.ORM中的锁和事务 2.Ajax 3.中间件:Middleware 3.1 什么是中间件? 3.2 django请求的生命周期 3.3 中间件可以定义的5个方法 3.4 自定义中间件的流程 ...

随机推荐

  1. 2021.06.29 mac系统下zsh: command not found:***报错问题

    最近老是遇到zsh: command not found:vue,zsh: command not found:nrm, zsh: command not found:tsc, zsh: comman ...

  2. vs2019远程调试win7系统的程序

    vs2019远程调试   一.安装vs2019远程调试工具 首先让调试的电脑(也就是不安装vs2019的电脑),安装vs2019远程调试工具:VS_RemoteTools.exe. 网址:进行下载.h ...

  3. BeanFactory与FactoryBean区别

    1. BeanFactory BeanFactory,以Factory结尾,表示它是一个工厂类(接口),用于管理Bean的一个工厂.在Spring中,BeanFactory是IOC容器的核心接口,也是 ...

  4. python 修改excel文件内容(修改excel文件日期每天保存一份)

    import xlrd import xlwt from xlutils.copy import copy import time import datetime def setStyle(name, ...

  5. 7. 基础增删改 - 使用Portal Webapi进行会员信息的增删改

    我们可以通过使用Portal Web API在Portal页面中跨所有Microsoft Dataverse表执行创建.更新和删除操作,下面我们就一起来看一下如何通过使用AJAX函数来进行操作. AJ ...

  6. HDF格式遥感影像批量转为TIFF格式:ArcPy实现

      本文介绍基于Python中ArcPy模块,实现大量HDF格式栅格图像文件批量转换为TIFF格式的方法.   首先,来看看我们想要实现的需求.   在一个名为HDF的文件夹下,有五个子文件夹:每一个 ...

  7. Python学习笔记--异常+模块+包

    异常的捕获 基本语法: 示例: 捕获指定异常 基本语法:--必写 示例: 捕获多个异常 示例: 捕获所有异常 示例: 异常else--可写可不写 示例: 异常finally(无论是否出现异常,都会去执 ...

  8. 如何理解redis两种不同的持久化方式

    其实redis就是一种高级的以键值对形式存储数据的数据库,而它的好处就是他可以支持数据的持久化,其实redis之所以会有这样的优点,主要是因为,redis的数据都是存放在内存中的,如果不配置持久化,那 ...

  9. 【Visual Leak Detector】在 QT 中使用 VLD(方式二)

    说明 使用 VLD 内存泄漏检测工具辅助开发时整理的学习笔记. 目录 说明 1. 使用前的准备 2. 在 QT 中使用 VLD 2.1 在项目 .pro 文件中指明路径 2.2 在 main.cpp ...

  10. Spring Boot 中的 ApplicationRunner 和 CommandLineRunner

    前言 一般项目中的初始化操作,初次遇见,妙不可言.如果你还有哪些方式可用于初始化操作,欢迎在评论中分享出来~ ApplicationRunner 和 CommandLineRunner Spring ...