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('库存不足,秒杀失败')
相关文章:
django中实现事务/django实现悲观锁乐观锁案例
django中实现事务的几种方式 # 1 全局开启事务---> 全局开启事务,绑定的是http请求响应整个过程DATABASES {default: {#全局开启事务,绑定的是http请求响应整个过程ATOMIC_REQUESTS: True, }}from django.db import transaction# 局部禁用事务trans…...
自动驾驶技术:改变交通出行的未来
自动驾驶技术,这个让人充满期待的技术,正在改变我们的交通方式,带来一种全新的出行体验。它可以让汽车、无人机等交通工具像人类驾驶一样自主行驶,通过人工智能、视觉计算、雷达、监控装置和全球定位系统协同合作,实现…...
5.利用matlab完成 符号矩阵的转置和 符号方阵的幂运算(matlab程序)
1.简述 Matlab符号运算中的矩阵转置 转置向量或矩阵 B A. B transpose(A) 说明 B A. 返回 A 的非共轭转置,即每个元素的行和列索引都会互换。如果 A 包含复数元素,则 A. 不会影响虚部符号。例如,如果 A(3,2) 是 12i 且 B A.࿰…...
为什么要自动化Web测试?
Web自动化是更快地实现所需结果的较佳方式。自动化测试在市场上引起了巨大的轰动。此软件测试过程可以让您使用正确的自动化测试工具和技术集自动执行测试过程。我们执行它是为了检查软件应用程序是否具有完全按照我们希望它执行的方式执行的勇气。 比以往更快地获得反馈 自动化…...
Spark_RDD的容错机制_数据丢失恢复
我们都知道Spark是弹性分布式数据集,数据会存储在多台机器上,那么如何确保在分布式数据计算中,数据不丢失就是其中的关键的部分。本文主要讲解一下Spark中的容错机制。 Spark 主要提供了3个层面的数据容错机制。分别是 调度层,RDD…...
VB+SQL期刊信息管理系统设计与实现
摘 要 本次毕业设计课题为“期刊信息管理系统”,该系统在正常运营中总是面对大量的读者信息、期刊信息以及两者相互作用产生的借刊信息,还刊信息。因此需要对读者资源、期刊资源、借刊信息、还刊信息进行管理,及时了解各个环节中信息的变更,有利于提高管理效率。 此次毕…...
如何在iPhone手机上修改手机定位和模拟导航?
如何在iPhone手机上修改手机定位和模拟导航? English 首先,你需要在Mac电脑上下载安装 Location Simulator/定位模拟工具 和 Runner 这两款应用程序。 完成安装后,打开软件,并用USB连接手机设备 修改iPhone手机定位和模拟导航 …...
Linux 当fork在for循环中的问题
以下代码会打印几个"A"? 例1.代码如下: int main(int argc, char* argv[],char* envp[]) { for(int i 0;i < 2; i ) { fork(); printf("A\n"); } exit(0); } 代码分析: //父进程for(int i …...
推断统计中非参数检验之卡方检验、列联表分析和游程检验
一、(卡方检验):赛马比赛的赛道会影响成绩吗 这里以一个实例赛马比赛的赛道是否会影响成绩为例,实际就是检验获胜频数与期望频数之间有无显著性差异。 import pandas as pdstep1 调用包 from scipy.stats import chisquare impor…...
AI社交来了,百度、Soul“双向奔赴”
随着科技的飞速进步和迅猛发展,AI技术已经开始渗透到教育、工作、社交、娱乐和健康多个领域,并为人们生活中的多个场景带来了诸多的创新和可能性。甚至可以说,AI技术已经深刻地介入到了我们日常生活的方方面面,让我们的生活方式发…...
【【verilog 典型电路设计之加法器树乘法器】】
verilog 典型电路设计之加法器树乘法器 加法器树乘法器 加法器树乘法器的设计思想是“移位后加”,并且加法运算采用加法器树的形式。乘法运算的过程是,被乘数与乘数的每一位相乘并且乘以相应的权值,最后将所得的结果相加,便得到了…...
选择最适合自己的NIO, 一探流技术
目录 一、Channel1、FileChannel代码示例2、DatagramChannel代码示例3、SocketChannel 和 ServerSocketChannel代码示例 二、Buffer1、ByteBuffer示例代码2、CharBuffer示例代码3、ShortBuffer、IntBuffer、LongBuffer、FloatBuffer、DoubleBuffer 等示例代码 三、Selector1、S…...
智能家居(3)---socket网络控制线程封装
封装socket网络线程实现对智能家居中各种灯光的控制 main.Pro(主函数) #include <stdio.h> #include "controlDevice.h" #include "inputCommand.h" #include <pthread.h>struct Devices *pdeviceHead NULL; //设备工厂链表…...
ubuntu 安装 emscripten 时 install latest 安装报错问题
学习官网参考:Compiling a New C/C Module to WebAssembly - WebAssembly | MDN (mozilla.org) 报错信息 形如: Error: Downloading URL https://storage.googleapis.com/webassembly/emscripten-releases-builds/linux/b90507fcf011da61bacfca613569…...
concrt140.dll丢失怎么恢复?教你5种修复方法
首先介绍一下concrt140.dll是什么 concrt140.dll是Microsoft Visual C Redistributable for Visual Studio 2015所需的一个动态链接库文件。它是用于支持C程序运行的重要组件之一。当系统中缺少或丢失concrt140.dll文件时,可能会导致一些程序无法正常运行。 首先&a…...
【Vue-Router】路由入门
路由(Routing)是指确定网站或应用程序中特定页面的方式。在Web开发中,路由用于根据URL的不同部分来确定应用程序中应该显示哪个内容。 构建前端项目 npm init vuelatest //或者 npm init vitelatest安装依赖和路由 npm install npm instal…...
蓝牙耳机运动耳机哪个好、好用的运动蓝牙耳机推荐
如今的蓝牙耳机已经成为手机的最佳伴侣,也是运动爱好者的必备装备。然而,在众多蓝牙耳机中做出选择可能会让人感到困惑。其实,在选购运动蓝牙耳机时需要注意的事项还挺多的,比如舒适度、稳定性和音质等多个方面,逐一对照这些要点来…...
大数据面试题:Kafka的ISR机制
面试题来源: 《大数据面试题 V4.0》 大数据面试题V3.0,523道题,679页,46w字 可回答:1)从ISR踢出去之后呢;2)一般Leader怎么判断Follower挂掉? 参考答案: …...
Windows:解决MySQL登录ERROR 1045 (28000): Access denied for user ‘root‘@‘localhost‘ (using passwor=YES)问题
我在下载的MySQL是8.0.32版本,刚下的时候没什么问题第二天启动MySQL服务就出现了 ERROR 1045 (28000): Access denied for user rootlocalhost (using password: YES) 或 ERROR 1045 (28000): Access denied for user rootlocalhost (using password: NO) 这样的问题…...
springboot整合kafka多数据源
整合kafka多数据源 项目背景依赖配置生产者消费者消息体 项目背景 在很多与第三方公司对接的时候,或者处在不同的网络环境下,比如在互联网和政务外网的分布部署服务的时候,我们需要对接多台kafka来达到我们的业务需求,那么当kafk…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...
C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...
嵌入式常见 CPU 架构
架构类型架构厂商芯片厂商典型芯片特点与应用场景PICRISC (8/16 位)MicrochipMicrochipPIC16F877A、PIC18F4550简化指令集,单周期执行;低功耗、CIP 独立外设;用于家电、小电机控制、安防面板等嵌入式场景8051CISC (8 位)Intel(原始…...
spring Security对RBAC及其ABAC的支持使用
RBAC (基于角色的访问控制) RBAC (Role-Based Access Control) 是 Spring Security 中最常用的权限模型,它将权限分配给角色,再将角色分配给用户。 RBAC 核心实现 1. 数据库设计 users roles permissions ------- ------…...
JS红宝书笔记 - 3.3 变量
要定义变量,可以使用var操作符,后跟变量名 ES实现变量初始化,因此可以同时定义变量并设置它的值 使用var操作符定义的变量会成为包含它的函数的局部变量。 在函数内定义变量时省略var操作符,可以创建一个全局变量 如果需要定义…...
简单介绍C++中 string与wstring
在C中,string和wstring是两种用于处理不同字符编码的字符串类型,分别基于char和wchar_t字符类型。以下是它们的详细说明和对比: 1. 基础定义 string 类型:std::string 字符类型:char(通常为8位)…...
