django中实现事务/django实现悲观锁乐观锁案例

django中实现事务的几种方式

# 1 全局开启事务---> 全局开启事务,绑定的是http请求响应整个过程DATABASES = {'default': {#全局开启事务,绑定的是http请求响应整个过程'ATOMIC_REQUESTS': True, }}from django.db import transaction# 局部禁用事务@transaction.non_atomic_requestsdef seckill(request):return HttpResponse('秒杀成功')# 2 一个视图函数在一个事物中# fbv开启from django.db import transaction@transaction.atomicdef seckill(request):return HttpResponse('秒杀成功')# cbv开启from django.db import transactionfrom rest_framework.views import APIViewclass SeckillAPIView(APIView):@transaction.atomicdef post(self, request):pass# 3 局部使用事务
from django.db import transaction
def seckill(request):with transaction.atomic():pass  # 都在一个事物中return HttpResponse('秒杀成功')

事物的回滚和保存点


# 1 普通事务操作(手动操作)
transaction.atomic()  # 开启事务
transaction.commit()  # 提交事务
transaction.rollback() # 回滚事务# 2 可以使用上下文管理器来控制(自动操作)
with transaction.atomic():  # 自动提交和回滚# 3 保存点-开启事务干了点事设置保存点1干了点事设置一个保存点2干了点事回滚到干完第二个事,回滚到保存点2'''
在事务操作中,我们还会经常显式地设置保存点(savepoint)
一旦发生异常或错误,我们使用savepoint_rollback方法让程序回滚到指定的保存点
如果没有问题,就使用savepoint_commit方法提交事务
'''from .models import Book
from django.db import transaction
def seckill(request):with transaction.atomic():# 设置回滚点,一定要开启事务sid = transaction.savepoint()print(sid)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('秒杀成功')
transaction.atomic()  # 开启事务
sid = transaction.savepoint() # 设置保存点
transaction.savepoint_rollback(sid) # 回滚到保存点
transaction.savepoint_commit(sid) #提交保存点

事务提交后,执行某个回调函数

# 有的时候我们希望当前事务提交后立即执行额外的任务,比如客户下订单后立即邮件通知卖家
###### 案例一##################
def send_email():print('发送邮件给卖家了')
def seckill(request):with transaction.atomic():# 设置回滚点,一定要开启事务sid = transaction.savepoint()print(sid)try:book = Book.objects.get(pk=1)book.count = book.count-1book.save()except Exception as e:# 如发生异常,回滚到指定地方transaction.savepoint_rollback(sid)else:transaction.savepoint_commit(sid)#transaction.on_commit(send_email)transaction.on_commit(lambda: send_sms.delay('1898288322'))return HttpResponse('秒杀成功')##### 案例二:celery中使用###
transaction.on_commit(lambda: send_sms.delay('1898288322'))

django实现悲观锁乐观锁案例

# 线上卖图书-图书表  图书名字,图书价格,库存字段-订单表: 订单id,订单名字# 表准备class Book(models.Model):name = models.CharField(max_length=32)price = models.IntegerField()  #count = models.SmallIntegerField(verbose_name='库存')class Order(models.Model):order_id = models.CharField(max_length=64)order_name = models.CharField(max_length=32)# 使用mysql
DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql','NAME': 'lqz','HOST': '127.0.0.1','PORT': '3306','USER': 'lqz','PASSWORD': '123',}
}# 创建lqz数据库

原生mysql悲观锁

begin; # 开启事务select * from goods where id = 1 for update;  # 行锁# order表中加数据update goods set stock = stock - 1 where id = 1; # 更新commit; #提交事务

orm实现上述

#1  使用悲观锁实现下单
@transaction.atomic  # 整个过程在一个事物中---》改两个表:book表减库存,订单表生成记录
def seckill(request):# 锁住查询到的book对象,直到事务结束sid = transaction.savepoint() # 保存点# 悲观锁: select_for_update()# 加锁了--》行锁还是表锁? 分情况,都有可能#book = Book.objects.select_for_update().filter(pk=1).first()  # 加悲观锁,行锁,锁住当前行if book.count > 0:print('库存可以,下单')# 订单表插入一条Order.objects.create(order_id=str(datetime.datetime.now()), order_name='测试订单')# 库存-1,扣减的时候,判断库存是不是上面查出来的库存,如果不是,就回滚time.sleep(random.randint(1, 4))  # 模拟延迟book.count=book.count-1book.save()transaction.savepoint_commit(sid)  # 提交,释放行锁return HttpResponse('秒杀成功')else:transaction.savepoint_rollback(sid) #回滚,释放行锁return HttpResponse('库存不足,秒杀失败')

乐观锁秒杀--》库存还有,有的人就没成功

# 2 乐观锁秒杀--普通版
@transaction.atomic
def seckill(request):# 锁住查询到的book对象,直到事务结束sid = transaction.savepoint()book = Book.objects.filter(pk=1).first()  # 没加锁count = book.countprint('现在的库存为:%s' % count)if book.count > 0:print('库存可以,下单')Order.objects.create(order_id=str(datetime.datetime.now()), order_name='测试订单-乐观锁')# 库存-1,扣减的时候,判断库存是不是上面查出来的库存,如果不是,就回滚# time.sleep(random.randint(1, 4))  # 模拟延迟res = Book.objects.filter(pk=1, count=count).update(count=count - 1)if res >= 1:  # 表示修改成功transaction.savepoint_commit(sid)return HttpResponse('秒杀成功')else:  # 修改不成功,回滚transaction.savepoint_rollback(sid)return HttpResponse('被别人改了,回滚,秒杀失败')else:transaction.savepoint_rollback(sid)return HttpResponse('库存不足,秒杀失败')

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/38880.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Unity 鼠标控制 UI 放大、缩小、拖拽

文章目录 1. 代码2. 测试场景 1. 代码 using UnityEngine; using UnityEngine.UI; using UnityEngine.EventSystems;public class UIDragZoom : MonoBehaviour, IDragHandler, IScrollHandler {private Vector2 originalSize;private Vector2 originalPosition;private RectTr…

css3 瀑布流布局遇见截断下一列展示后半截现象

css3 瀑布流布局遇见截断下一列展示后半截现象 注:css3实现瀑布流布局简直不要太香~~~~~ 场景-在uniapp项目中 当瀑布流布局column-grap:10px 相邻两列之间的间隙为10px,column-count:2,2列展…

面试之快速学习C++11-完美转发,nullptr, shared_ptr,unique_ptr,weak_ptr,shared_from_this

完美转发及其实现 函数模版可以将自己的参数完美地转发给内部调用的其他函数。所谓完美,即不仅能准确地转发参数的值,还能保证被转发参数的左右值属性不变引用折叠:如果任一引用为左值引用,则结果为左值引用,否则为右…

在阿里云服务器上安装Microsoft SharePoint 2016流程

本教程阿里云百科分享如何在阿里云ECS上搭建Microsoft SharePoint 2016。Microsoft SharePoint是Microsoft SharePoint Portal Server的简称。SharePoint Portal Server是一个门户站点,使得企业能够开发出智能的门户站点。 目录 背景信息 步骤一:添加…

【Leetcode 30天Pandas挑战】学习记录 下

题目列表: 数据统计:2082. The Number of Rich Customers1173. Immediate Food Delivery I1907. Count Salary Categories 数据分组1741. Find Total Time Spent by Each Employee511. Game Play Analysis I2356. Number of Unique Subjects Taught by Each Teacher…

无涯教程-Perl - setgrent函数

描述 此功能将枚举设置(或重置)到组条目集的开头。该函数应在第一次调用getgrent之前调用。 语法 以下是此函数的简单语法- setgrent返回值 此函数不返回任何值。 例 以下是显示其基本用法的示例代码- #!/usr/bin/perl -wwhile( ($name,$passwd,$gid,$members)getgrent…

ide internal errors【bug】

ide internal errors【bug】 前言版权ide internal errors错误产生相关资源解决1解决2 设置虚拟内存最后 前言 2023-8-15 12:36:59 以下内容源自《【bug】》 仅供学习交流使用 版权 禁止其他平台发布时删除以下此话 本文首次发布于CSDN平台 作者是CSDN日星月云 博客主页是h…

C++模板的分离编译问题

本文主要是了解一下为什么模板的定义和声明不能分开,需要简单了解一下编译的四个阶段。 一、理解编译大致流程 整个编译流程分为:预处理、编译、汇编、链接,这里以源文件main.cpp文件为例。 预处理:对源文件进行宏替换、去注释、…

CentOS8防火墙基础操作应用

查看防火墙某个端口是否开放 firewall-cmd --query-port80/tcp 开放防火墙端口80 firewall-cmd --zonepublic --add-port80/tcp --permanent 关闭80端口 firewall-cmd --zonepublic --remove-port80/tcp --permanent 配置立即生效firewall-cmd --reload 查看防火墙状态 s…

代码随想录算法训练营第58天|动态规划part15|392.判断子序列、115.不同的子序列

代码随想录算法训练营第58天|动态规划part15|392.判断子序列、115.不同的子序列 392.判断子序列 392.判断子序列 思路: (这道题也可以用双指针的思路来实现,时间复杂度也是O(n)) 这道题应该算是编辑距…

[Android 11]使用Android Studio调试系统应用之Settings移植(七):演示用AS编译错误问题

文章目录 1. 篇头语2. 系列文章3. AS IDE的配置3.1 AS版本3.2 Gradle JDK 版本4. JDK的下载5. AS演示工程地址6.其他版本JDK导致的错误1. 篇头语 距离2021年开始,系列文章发表已经有近两年了,依旧有网友反馈一些gitee上演示源码编译的一些问题,这里就记录一下。 2. 系列文章…

uniApp引入vant2

uniApp引入vant2 1、cnpm 下载:cnpm i vantlatest-v2 -S2、main.js文件引入 import Vant from ./node_modules/vant/lib/vant;Vue.use(Vant);3.app.vue中引入vant 样式文件 import /node_modules/vant/lib/index.css;

tomcat服务七层搭建动态页面查看

一个服务器多实例复制完成 配置tomcat多实例的环境变量 vim /etc/profile.d/tomcat.sh配置tomcat1和tomcat2的环境变量 进入tomcat1修改配置 测试通信端口是否正常 连接正常 toncat 2 配置修改 修改这三个 端口配置修改完成 修改tomcat1 shudown 分别把启动文件指向tomcat1…

数据结构--最短路径 Dijkstra算法

数据结构–最短路径 Dijkstra算法 Dijkstra算法 计算 b e g i n 点到各个点的最短路 \color{red}计算\ begin\ 点到各个点的最短路 计算 begin 点到各个点的最短路 如果是无向图,可以先把无向图转化成有向图 我们需要2个数组 final[] (标记各顶点是否已…

【ARM 嵌入式 编译系列 10.1 -- GCC 编译缩减可执行文件 elf 文件大小】

文章目录 上篇文章:ARM 嵌入式 编译系列 10 – GCC 编译缩减可执行文件 elf 文件大小 接着上篇文章 ARM 嵌入式 编译系列 10 – GCC 编译缩减可执行文件 elf 文件大小 的介绍,我们看下如何进一步缩小可执行文件test的大小。上篇文章通过 strip --strip-…

RunnerGo的相比较JMeter优势,能不能替代?

目前在性能测试领域市场jmeter占有率是非常高的,主要原因是相对比其他性能测试工具使用更简单(开源、易扩展),功能更强大(满足多种协议的接口),但是随着研发协同的升级,平台化的性能…

进程的概念和特征

进程的概念和特征 进程的概念进程的特征 进程的概念 在多道程序环境下,允许多个程序并发执行,此时他们将失去封闭性,并具有间断性及不可再现性的特征。为此引入了进程(process)的概念,以便更好的描述和控制…

【Java】常用工具——异常

1. try-catch-finnaly try必须和catch或者finally组合使用; public class TryDemoOne {public static void main(String[] args) {Scanner input new Scanner(System.in);System.out.println("输入第1个整数:");int one input.nextInt();S…

主流的嵌入式微处理器

目前主流的嵌入式微处理器系列有: ARM系列 MIPS系列 PowerPC系列 Super H系列 一、MPC/PPC系列 PowerPC(简称PPC),其基本设计源自IBM的POWER.1991年,APPLE(苹果电脑)、IBM、Motorola(摩托罗拉)组成的AIM联盟发展出Power微处理器…

mybatis-plus 根据指定字段 批量 删除/修改

mybatis-plus 提供了根据id批量更新和修改的方法,这个大家都不陌生 但是当表没有id的时候怎么办 方案一: 手写SQL方案二: 手动获取SqlSessionTemplate 就是把mybatis plus 干的事自己干了方案三 : 重写 executeBatch 方法结论: mybatis-plus 提供了根据id批量更新和修改的方法,…