django orm 乐观锁

# 类视图 (并发,乐观锁)
class MyView(View):
    
    @transaction.atomic
    def post(self, request):
        '''订单创建'''
        count = 3   # 订购3件商品
        
        # 设置事务保存点
        s1 = transaction.savepoint()
        
        # 乐观锁,最多尝试5次
        for i in range(5):
            # 查询商品的信息(库存)
            try:
                sku = GoodsSKU.objects.get(id=1)
            except:
                # 商品不存在
                transaction.savepoint_rollback(s1)
                return JsonResponse({'res': 1, 'errmsg': '商品不存在'})
 
            # 判断商品的库存
            if count > sku.stock:
                transaction.savepoint_rollback(s1)
                return JsonResponse({'res': 2, 'errmsg': '商品库存不足'})
 
            # 更新商品的库存和销量
            orgin_stock = sku.stock   # 原库存 (数据库隔离级别必须是Read Committed;如果是Repeatable Read,那么多次尝试读取的原库存都是一样的,读不到其他线程提交更新后的数据。)
            new_stock = orgin_stock - count   # 更新后的库存
            new_sales = sku.sales + count   # 更新后的销量
 
            # update 商品表 set stock=new_stock, sales=new_sales where id=1 and stock = orgin_stock
            # 通过where子句中的条件判断库存是否进行了修改。(并发,乐观锁)
            # 返回受影响的行数
            res = GoodsSKU.objects.filter(id=1, stock=orgin_stock).update(stock=new_stock, sales=new_sales)  
            if res == 0:  # 如果修改失败
                if i == 4:
                    # 如果尝试5次都失败
                    transaction.savepoint_rollback(s1)
                    return JsonResponse({'res': 3, 'errmsg': '下单失败'})
                continue  # 再次尝试
 
            # 否则更新成功
            # 跳出尝试循环
            break
 
 
        # 提交事务
        transaction.savepoint_commit(s1)
 
        # 返回应答
        return JsonResponse({'res': 4, 'message': '创建成功'})

posted on 2021-03-01 20:37  Plyc  阅读(155)  评论(0编辑  收藏  举报

导航