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 

猜你喜欢

转载自www.cnblogs.com/lvye001/p/10208217.html