真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

基于Django的樂觀鎖與悲觀鎖解決訂單并發(fā)問題詳解-創(chuàng)新互聯(lián)

前言

創(chuàng)新互聯(lián)主營改則網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營網(wǎng)站建設(shè)方案,app軟件開發(fā)公司,改則h5小程序定制開發(fā)搭建,改則網(wǎng)站營銷推廣歡迎改則等地區(qū)企業(yè)咨詢

訂單并發(fā)這個問題我想大家都是有一定認識的,這里我說一下我的一些淺見,我會盡可能的讓大家了解如何解決這類問題。

在解釋如何解決訂單并發(fā)問題之前,需要先了解一下什么是數(shù)據(jù)庫的事務(wù)。(我用的是mysql數(shù)據(jù)庫,這里以mysql為例)

1)     事務(wù)概念

一組mysql語句,要么執(zhí)行,要么全不不執(zhí)行。

 2)  mysql事務(wù)隔離級別

Read Committed(讀取提交內(nèi)容)

如果是Django2.0以下的版本,需要去修改到這個隔離級別,不然樂觀鎖操作時無法讀取已經(jīng)被修改的數(shù)據(jù)

RepeatableRead(可重讀)

這是這是Mysql默認的隔離級別,可以到mysql的配置文件中去修改;

transcation-isolation = READ-COMMITTED

在mysql配置文件中添加這行然后重啟mysql就可以將事務(wù)隔離級別修改至Read Committed

其他事務(wù)知識這里不會用到就不浪費時間去做介紹了。

悲觀鎖:開啟事務(wù),然后給mysql的查詢語句最后加上for update。

這是在干什么呢。可能大家有些不理解,其實就是給資源加上和多線程中加互斥鎖一樣的東西,確保在一個事務(wù)結(jié)束之前,別的事務(wù)無法對該數(shù)據(jù)進行操作。

下面是悲觀鎖的代碼,加鎖和解鎖都是需要消耗CPU資源的,所以在訂單并發(fā)少的情況使用樂觀鎖會是一個更好的選擇。

class OrderCommitView(View):
  """悲觀鎖"""
  # 開啟事務(wù)裝飾器
  @transaction.atomic
  def post(self,request):
    """訂單并發(fā) ———— 悲觀鎖"""
    # 拿到商品id
    goods_ids = request.POST.getlist('goods_ids')
 
    # 校驗參數(shù)
    if len(goods_ids) == 0 :
      return JsonResponse({'res':0,'errmsg':'數(shù)據(jù)不完整'}) 
    # 當前時間字符串
    now_str = datetime.now().strftime('%Y%m%d%H%M%S') 
    # 訂單編號
    order_id = now_str + str(request.user.id)
    # 地址
    pay_method = request.POST.get('pay_method')
    # 支付方式
    address_id = request.POST.get('address_id')
    try:
      address = Address.objects.get(id=address_id)
    except Address.DoesNotExist:
      return JsonResponse({'res':1,'errmsg':'地址錯誤'}) 
    # 商品數(shù)量
    total_count = 0
    # 商品總價
    total_amount = 0 
     # 獲取redis連接
    conn = get_redis_connection('default')
    # 拼接key
    cart_key = 'cart_%d' % request.user.id  
    #
    # 創(chuàng)建保存點
    sid = transaction.savepoint() 
    order_info = OrderInfo.objects.create(
      order_id = order_id,
      user = request.user,
      addr = address,
      pay_method = pay_method,
      total_count = total_count,
      total_price = total_amount
    ) 
    for goods_id in goods_ids:
      # 嘗試查詢商品
      # 此處考慮訂單并發(fā)問題,
      try:
        # goods = Goods.objects.get(id=goods_id) # 不加鎖查詢
        goods = Goods.objects.select_for_update().get(id=goods_id) # 加互斥鎖查詢
      except Goodsgoods.DoesNotExist:
        # 回滾到保存點
        transaction.rollback(sid)
        return JsonResponse({'res':2,'errmsg':'商品信息錯誤'})
      # 取出商品數(shù)量
      count = conn.hget(cart_key,goods_id)
      if count is None:
        # 回滾到保存點
        transaction.rollback(sid)
        return JsonResponse({'res':3,'errmsg':'商品不在購物車中'}) 
      count = int(count) 
      if goods.stock < count:
        # 回滾到保存點
        transaction.rollback(sid)
        return JsonResponse({'res':4,'errmsg':'庫存不足'}) 
      # 商品銷量增加
      goods.sales += count
      # 商品庫存減少
      goods.stock -= count
      # 保存到數(shù)據(jù)庫
      goods.save() 
      OrderGoods.objects.create(
        order = order_info,
        goods = goods,
        count = count,
        price = goods.price
      ) 
      # 累加商品件數(shù)
      total_count += count
      # 累加商品總價
      total_amount += (goods.price) * count 
    # 更新訂單信息中的商品總件數(shù)
    order_info.total_count = total_count
    # 更新訂單信息中的總價格
    order_info.total_price = total_amount + order_info.transit_price
    order_info.save()
 
    # 事務(wù)提交
    transaction.commit() 
    return JsonResponse({'res':5,'errmsg':'訂單創(chuàng)建成功'})

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機、免備案服務(wù)器”等云主機租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。


網(wǎng)頁題目:基于Django的樂觀鎖與悲觀鎖解決訂單并發(fā)問題詳解-創(chuàng)新互聯(lián)
分享鏈接:http://weahome.cn/article/ppipe.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部