后端在生成訂單表的時候,牽扯到如下的知識點:
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