Django中事物的使用

from django.db import transaction

@transaction.atomic
通过transaction的@transaction.atomic装饰器来开启事务,在视图逻辑涉及数据库操作的地方添加事物保存点,在操作不满足时进行事物回滚,在操作满足是进行事物提交

# 前端传递的参数:地址id(addr_id) 支付方式(pay_method) 用户要购买的商品id字符串(sku_ids)
# mysql事务: 一组sql操作,要么都成功,要么都失败
# 高并发:秒杀
# 支付宝支付
class OrderCommitView(View):
'''订单创建'''
@transaction.atomic
def post(self, request):
'''订单创建'''
# 判断用户是否登录
user = request.user
if not user.is_authenticated():
# 用户未登录
return JsonResponse({'res': 0, 'errmsg': '用户未登录'}) # 接收参数
addr_id = request.POST.get('addr_id')
pay_method = request.POST.get('pay_method')
sku_ids = request.POST.get('sku_ids') # 校验参数
if not all([addr_id, pay_method, sku_ids]):
return JsonResponse({'res': 1, 'errmsg': '参数不完整'}) # 校验支付方式
if pay_method not in OrderInfo.PAY_METHODS.keys():
return JsonResponse({'res': 2, 'errmsg': '不支持的支付方式'}) # 校验地址
try:
addr = Address.objects.get(id=addr_id)
except Address.DoesNotExist:
# 地址不存在
return JsonResponse({'res': 3, 'errmsg': '地址非法'}) # todo:创建订单核心业务 #组织参数
#订单id:20190416222615+用户id
order_id = datetime.now().strftime('%Y%m%d%H%M%S')+str(user.id) # 运费
transit_price = 10 # 总数目和总金额
total_count = 0
total_price = 0 # 设置事务保存点
save_id = transaction.savepoint()
try:
# todo: 向df_order_info表中添加一条记录
order = OrderInfo.objects.create(order_id=order_id,
user=user,
addr=addr,
pay_method=pay_method,
total_count=total_count,
total_price=total_price,
transit_price=transit_price) # todo: 用户的订单中有几个商品,需要向df_order_goods表中加入几条记录
conn = get_redis_connection('default')
cart_key = 'cart_%d' % user.id sku_ids = sku_ids.split(',')
for sku_id in sku_ids:
# 获取商品的信息
try:
sku = GoodsSKU.objects.get(id=sku_id)
except:
# 商品不存在,进行事物回滚
transaction.savepoint_rollback(save_id)
return JsonResponse({'res': 4, 'errmsg': '商品不存在'}) # 从redis中获取用户所要购买的商品数量
count = conn.hget(cart_key, sku_id) # todo: 判断商品的库存
if int(count) > sku.stock:
# 库存不足,进行事物回滚
transaction.savepoint_rollback(save_id)
return JsonResponse({'res': 6, 'errmsg': '商品库存不足'}) # todo: 向df_order_goods表中添加一条记录
OrderGoods.objects.create(order=order,
sku=sku,
count=count,
price=sku.price)
# todo: 更新商品的库存和销量
sku.stock -= int(count)
sku.sales += int(count)
sku.save() # todo: 累加计算订单商品的总数量和总价格
amount = sku.price*int(count)
total_count += int(count)
total_price += amount # todo: 更新订单信息表中的商品的总数量和总价格
order.total_count = total_count
order.total_price = total_price
order.save()
except Exception as e:
transaction.savepoint_rollback(save_id)
return JsonResponse({'res': 7, 'errmsg': '下单失败'}) # 提交事务
transaction.savepoint_commit(save_id) # todo: 清除用户购物车中对应的记录
conn.hdel(cart_key, *sku_ids) # 返回应答
return JsonResponse({'res': 5, 'message': '创建成功'})

  

Django中MySQL事务的使用的更多相关文章

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

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

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

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

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

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

  4. Django中的事务与ajax

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

  5. django中的事务管理

    在讲解之前首先来了解一下数据库中的事务. 什么是数据库中的事务? 热心网友回答: ():事务(Transaction)是并发控制的单位,是用户定义的一个操作序列.这些操作要么都做,要么都不做,是一个不 ...

  6. django中mysql数据库设置错误解决方法

    刚在django中settings.py进行设置mysql数据库. 当进行执行python manage.py shell命令时会报以下错误: 只需要在settings.py中 DATABASES = ...

  7. Django中MySQL读写分离技术

    最近需要用到Django的MySQL读写分离技术,查了一些资料,把方法整理了下来. 在Django里实现对MySQL的读写分离,实际上就是将不同的读写请求按一定的规则路由到不同的数据库上(可以是不同类 ...

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

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

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

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

随机推荐

  1. Springboot 事务注解--- @Transactional

    spring boot @Transactional事物处理    spring boot 添加事物使用 @Transactional注解 简单使用 在启动类上方添加 @EnableTransacti ...

  2. coding++:Linux - Shell - 常用命令

    1.在多个文件中 查找内容 find . -type f -name "*.html" | xargs grep "1"

  3. spring中BeanPostProcessor之一:InstantiationAwareBeanPostProcessor(03)

    前面介绍了InstantiationAwareBeanPostProcessor后置处理器的postProcessBeforeInstantiation和postProcessAfterInstant ...

  4. LeetCode | 力扣周赛C题 5370. 设计地铁系统

    请你实现一个类 UndergroundSystem ,它支持以下 3 种方法: checkIn(int id, string stationName, int t) 编号为 id 的乘客在 t 时刻进 ...

  5. C++11中的四种类型转换

    static_cast 基础数据类型转换(基本类型) 同一继承体系中类型的转换(父子类型) 任意类型与空指针(void *)之间的转换(指针类型) dynamic_cast 执行派生类指针或引用与基类 ...

  6. Python爬虫利器 cURL你用过吗?

    hello,小伙伴们,今天给大家分享的开源项目是一个python爬虫利器,感兴趣的小伙伴看完这篇文章不妨去尝试一下,这个开源项目就是curlconverter,不知道小伙伴们分析完整个网站后去code ...

  7. 22.3 Extends 构造方法的执行顺序

    /** 1.有子父类继承关系的类中,创建父类对象未调用,执行父类无参构造* 2.有子父类继承关系的类中,创建子类对象未调用,执行顺序:默认先调用 父类无参构造---子类无参构造* 在子类的构造方法的第 ...

  8. bit/byte/ascii/unicode

    bit(位).byte(字节).ASCII.Unicode 和 UTF-8位和字节的关系bit 电脑记忆体中最小的单位,在二进位电脑系统中,每一bit 可以代表0 或 1 的数位讯号byte一个byt ...

  9. MathJax的基本使用

    MathJax是一个开放源代码的JavaScript显示引擎,适用于所有现代浏览器中的LaTeX.MathML和AsciMath表示法. MathJax官网为 https://www.mathjax. ...

  10. python 字节码死磕

    前言:  如果你跟我一样,对python的字节码感兴趣,想了解python的代码在内存中到底是怎么去运行的,那么你可以继续往下看,如果你是python新手,我建议你移步它处,本文适合有点基础的pyth ...