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 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM