django 保存订单乐观锁的使用

Posted lvye001

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了django 保存订单乐观锁的使用相关的知识,希望对你有一定的参考价值。

后端在生成订单表的时候,牵扯到如下的知识点:

1 事物

2 高并发

3 时间函数的使用

 

一,事务:

from django.db import transaction
 
save_id = transaction.savepoint()  # 创建保存点
 
transaction.savepoint_rollback(save_id)  # 回退(回滚)到保存点
 
transaction.savepoint_commit(save_id)  # 提交保存点

例子用法:

from django.db import transaction

with transaction.atomic():

  # 创建保存点
  save_ponit=transaction.savepoint()
       try:
          # 4、生成订单基本信息表
          order = OrderInfo.objects.create(
          ......
              )

     except:
       transaction.savepoint_rollback(save_ponit)
     

      else:
        transaction.savepoint_commit(save_ponit)

 

2 高并发

当多个用户同时去抢同一个商品的时候,就有可能会出现库存不足,把一些错误的数据保存到数据库中

技术分享图片

解决的方法: 采用悲观锁,采用乐观锁,采用队列,排队下单

1,悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁。

悲观锁用法:

select_for_update(nowait=False)   #nowait=False默认,置为True则使查询不阻塞,如果有其它事务持有冲突的锁,则报databaseError错误

返回queryset,并将需要更新的行锁定,类似于SELECT ... FOR UPDATE的操作。

entries = Entry.objects.select_for_update().filter(author=request.user)

技术分享图片

所有匹配的entries都会被锁定直到此次事务结束。

 

2,乐观锁

顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,

先查询

技术分享图片

技术分享图片

解析以上代码,先查询数据库库存数量,定义个库存变量,然后当保存订单的时候已该字段为过滤条件进行过滤修改,

如果修改失败,则返回0,并重试3次(自定义重试次数),

 

该方法只适用于订单并发较少的情况,如果失败次数过多,会带给用户不良体验,同时适用该方法要注意数据库的隔离级别一定要设置为Read Committed 。

最好在使用乐观锁之前查看一下数据库的隔离级别,mysql中查看事物隔离级别的命令为

select @@global.tx_isolation;

 

3,时间函数的使用

from datetime import datetime
order_id = datetime.now().strftime(%Y%m%d%H%M%S) + %06d % user.id

上面这个一般作为商品订单号使用。

 

 

详情信息可以:

https://blog.csdn.net/qq_36012543/article/details/79679690?utm_source=copy 







以上是关于django 保存订单乐观锁的使用的主要内容,如果未能解决你的问题,请参考以下文章

java中悲观锁和乐观锁的区别

乐观锁和悲观锁的使用场景及应用——Java高并发系列学习笔记

乐观锁和悲观锁的使用场景及应用——Java高并发系列学习笔记

乐观锁的实现

锁的原理和使用场景,乐观锁悲观锁公平锁非公平锁,基于数据库RedisZookeeper实现分布式锁的原理及代码实现

数据库锁之乐观锁