django實現(xiàn)悲觀鎖樂觀鎖的項目實踐
前期準備
# 線上賣圖書
-圖書表 圖書名字,圖書價格,庫存字段
-訂單表: 訂單id,訂單名字
# 表準備
class Book(models.Model):
name = models.CharField(max_length=32)
price = models.IntegerField() #
count = models.SmallIntegerField(verbose_name='庫存')
class Order(models.Model):
order_id = models.CharField(max_length=64)
order_name = models.CharField(max_length=32)
# 使用mysql
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'lqz',
'HOST': '127.0.0.1',
'PORT': '3306',
'USER': 'lqz',
'PASSWORD': '123',
}
}
# 創(chuàng)建lqz數(shù)據(jù)庫1.原生mysql悲觀鎖
begin; # 開啟事務(wù) select * from goods where id = 1 for update; # 行鎖 # order表中加數(shù)據(jù) update goods set stock = stock - 1 where id = 1; # 更新 commit; #提交事務(wù)
2.orm實現(xiàn)上述(悲觀鎖)
#1 使用悲觀鎖實現(xiàn)下單
@transaction.atomic # 整個過程在一個事物中---》改兩個表:book表減庫存,訂單表生成記錄
def seckill(request):
# 鎖住查詢到的book對象,直到事務(wù)結(jié)束
sid = transaction.savepoint() # 保存點
# 悲觀鎖: select_for_update()
# 加鎖了--》行鎖還是表鎖? 分情況,都有可能
#
book = Book.objects.select_for_update().filter(pk=1).first() # 加悲觀鎖,行鎖,鎖住當(dāng)前行
if book.count > 0:
print('庫存可以,下單')
# 訂單表插入一條
Order.objects.create(order_id=str(datetime.datetime.now()), order_name='測試訂單')
# 庫存-1,扣減的時候,判斷庫存是不是上面查出來的庫存,如果不是,就回滾
time.sleep(random.randint(1, 4)) # 模擬延遲
book.count=book.count-1
book.save()
transaction.savepoint_commit(sid) # 提交,釋放行鎖
return HttpResponse('秒殺成功')
else:
transaction.savepoint_rollback(sid) #回滾,釋放行鎖
return HttpResponse('庫存不足,秒殺失敗')3 樂觀鎖秒殺--》庫存還有,有的人就沒成功
# 2 樂觀鎖秒殺--普通版
@transaction.atomic
def seckill(request):
# 鎖住查詢到的book對象,直到事務(wù)結(jié)束
sid = transaction.savepoint()
book = Book.objects.filter(pk=1).first() # 沒加鎖
count = book.count
print('現(xiàn)在的庫存為:%s' % count)
if book.count > 0:
print('庫存可以,下單')
Order.objects.create(order_id=str(datetime.datetime.now()), order_name='測試訂單-樂觀鎖')
# 庫存-1,扣減的時候,判斷庫存是不是上面查出來的庫存,如果不是,就回滾
# time.sleep(random.randint(1, 4)) # 模擬延遲
res = Book.objects.filter(pk=1, count=count).update(count=count - 1)
if res >= 1: # 表示修改成功
transaction.savepoint_commit(sid)
return HttpResponse('秒殺成功')
else: # 修改不成功,回滾
transaction.savepoint_rollback(sid)
return HttpResponse('被別人改了,回滾,秒殺失敗')
else:
transaction.savepoint_rollback(sid)
return HttpResponse('庫存不足,秒殺失敗')到此這篇關(guān)于django實現(xiàn)悲觀鎖樂觀鎖的項目實踐的文章就介紹到這了,更多相關(guān)django 悲觀鎖樂觀鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python中三種輸出格式總結(jié)(%,format,f-string)
在Python語言編程中,我們會與字符串打交道,那務(wù)必會輸出字符串來查看字符串的內(nèi)容,下面這篇文章主要給大家介紹了關(guān)于python中三種輸出格式的相關(guān)資料,三種格式分別是%,format,f-string,需要的朋友可以參考下2022-03-03
Python檢查和同步本地時間(北京時間)的實現(xiàn)方法
這篇文章主要介紹了Python檢查和同步本地時間(北京時間)的實現(xiàn)方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-12-12
Python基于Tkinter開發(fā)一個爬取B站直播彈幕的工具
這篇文章主要介紹了Python Tkinter如何開發(fā)一個爬取B站直播彈幕的工具,幫助大家更好的利用python進行圖形界面的開發(fā)學(xué)習(xí),感興趣的朋友可以了解下2021-05-05
使用python的pandas讀取excel文件中的數(shù)據(jù)詳情
這篇文章主要介紹了使用python的pandas讀取excel文件中的數(shù)據(jù)詳情,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-09-09
python調(diào)用機器喇叭發(fā)出蜂鳴聲(Beep)的方法
這篇文章主要介紹了python調(diào)用機器喇叭發(fā)出蜂鳴聲(Beep)的方法,實例分析了Python調(diào)用winsound模塊的使用技巧,需要的朋友可以參考下2015-03-03
Python cookbook(數(shù)據(jù)結(jié)構(gòu)與算法)篩選及提取序列中元素的方法
這篇文章主要介紹了Python cookbook(數(shù)據(jù)結(jié)構(gòu)與算法)篩選及提取序列中元素的方法,涉及Python列表推導(dǎo)式、生成器表達式及filter()函數(shù)相關(guān)使用技巧,需要的朋友可以參考下2018-03-03

