mysql乐观锁 秒杀_乐观锁实现电商网站秒杀

classOrderCommitView(view):

@transaction.atomic

def post(self, request):

# 判断用户是否登录

user = request.user

if not user.is_authenticated():

return JsonResponse("res":0,"error_msg":"用户未登录")

addr_id = request.POST.get('addr_id')

pay_method = request.POST.get('pay_methon')

sku_ids = request.POST.get('sku_ids')

if not all([addr_id, pay_method, sku_ids]):

return JsonResponse({'res':1, 'error_msg':'params not enough'})

# 校验支付方式

if pay_method not in OrderInfo.PAY_METHODS.keys():

return JsonResponse('ret':2,'error_msg':'非法支付方式')

# 校验地址

try:

addr = Address.objects.get(id=addr_id)

except Address.DoesNotExist:

return JsonResponse('ret':3,'error_msg':"地址非法")

# 创建订单核心业务

订单id :日期加用户的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_oeder_info表中添加一条记录

order = OrderInfo.objects.create(order_id=order,user=user,pay_method=pay_method,total_count=total_count,total_price=total_price)

conn = get_redis_connection('default')

cart_key = 'cart_%d'%user.id

sku_ids = sku_ids.split(',')

for sku_id in sku_ids:

# 获取商品信息

# for 循环3次 尝试都能下单成功

for i in range(3):

try:

sku = GoodsSKU.objects.get(id=sku_id)

except:

# 商品不存在

transaction.savepoint_rollback(save_id)

return JsonResponse({'ret':4,'error_msg':"商品不存在"})

# 从redis中获取用户需要购买的商品的数量

count = conn.hget(cart_key,sku.stock)

# todo 判断商品的库存

if int(count) > sku.stock:

transaction.savepoint_rollback(save_id)

return JsonResponse({'res':6,'error_msg':'商品库存不足'})

# todo 更新商品的库存和销量

origin_stock = sku.stock

new_stock = origin_stock - int(count)

new_sales = sku.sales + int(count)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL中的乐观实现通常依赖于版本号或时间戳。其主要思路是,在数据更新时,先获取当前数据的版本号或时间戳,然后在更新数据时比较当前版本号或时间戳与更新前获取的版本号或时间戳是否相同,如果相同则执行更新操作,否则认为数据已经被其他事务更新,拒绝本次更新操作。 具体实现可以通过以下步骤来完成: 1. 在数据表中添加版本号或时间戳字段,用于记录数据的版本信息。 2. 在更新数据时,先查询出待更新数据的版本号或时间戳,并保存在变量中。 3. 执行更新操作前,再次查询数据的版本号或时间戳,并与之前保存的版本号或时间戳进行比较。 4. 如果两者相同,则执行更新操作;否则认为数据已经被其他事务更新,拒绝本次更新操作。 5. 在更新操作完成后,更新数据的版本号或时间戳。 具体实现可以使用MySQL的UPDATE语句,通过添加条件判断来实现乐观的效果。例如: ``` UPDATE table_name SET column1 = value1, ..., version = new_version WHERE id = target_id AND version = old_version; ``` 其中,`target_id`表示待更新数据的ID,`old_version`表示之前查询出的数据版本号或时间戳,`new_version`表示更新后的数据版本号或时间戳。如果`old_version`与`version`字段的值相同,说明数据没有被其他事务修改,可以执行更新操作;否则更新操作不会执行,可以通过返回值判断是否更新成功。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值