# 类视图 (并发,乐观锁) 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': '创建成功'})