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. nim博弈 LightOJ - 1253

    主要是写一下nim博弈的理解,这个题有点奇怪,不知道为什么判断奇偶性,如果有大佬知道还请讲解一下. //nim博弈 //a[0]~a[i] 异或结果为k 若k=0 则为平衡态 否则为非平衡态 //平衡 ...

  2. postman设置全局变量及参数化

    笔者第一次记录使用过程,仅供参考 测试过程中接口的前缀都是一样的,所以我们可以将这个前缀作为全局变量来使用 首先,打开postman点击这里的小齿轮设置 在这里就可以进行变量的一个添加,添加好之后记住 ...

  3. Web Scraper 性能测试 (-_-)

    刚在研究 Python 爬虫的时候,看到了个小白工具,叫 Web Scraper,于是来测试下好不好用. Web Scraper 是什么? 它是一个谷歌浏览器的插件, 用于批量抓取网页信息, 主要特点 ...

  4. Fedora20在神州战神K650D1安装过程,使用netinstall和Dvd.iso镜像安装。

    最近新买一笔记本,神州战神K650D-i5 D1.仍旧安装双系统,WIndows7+Fedora20.磁盘分区是这样的: 第一主分区 /boot ext4 20G 第二主分区 / ext4 70G 第 ...

  5. 图的深度优先搜索dfs

    图的深度优先搜索: 1.将最初访问的顶点压入栈: 2.只要栈中仍有顶点,就循环进行下述操作: (1)访问栈顶部的顶点u: (2)从当前访问的顶点u 移动至顶点v 时,将v 压入栈.如果当前顶点u 不存 ...

  6. ThreadAbortException是可以传递的

    今天在写线程Aborted代码时,发现嵌套的try catch中的ThreadAbortException错误是可以从内部传递到外部的,想想这也是必然的,在内部该线程已经中断了,外部必然是中断了,再仔 ...

  7. mabatis入门五 高级结果映射

    一.创建测试的表和数据 1.创建表 1CREATE TABLE items ( 2 id INT NOT NULL AUTO_INCREMENT, 3 itemsname VARCHAR(32) NO ...

  8. python之xlrd和xlwt模块读写excel使用详解

    一.xlrd模块和xlwt模块是什么      xlrd模块是python第三方工具包,用于读取excel中的数据:      xlwt模块是python第三方工具包,用于往excel中写入数据: 二 ...

  9. Codeforces 631 (Div. 2) D. Dreamoon Likes Sequences 位运算^ 组合数 递推

    https://codeforces.com/contest/1330/problem/D 给出d,m, 找到一个a数组,满足以下要求: a数组的长度为n,n≥1; 1≤a1<a2<⋯&l ...

  10. uCOS-II简介及移植uCOS-II到STM32F103平台详细步骤

    1.参考博客:https://blog.csdn.net/wang328452854/article/details/78486458 2.uCOS(也有人叫uC/OS)由美国人 Jean Labro ...