django中實現事務/django實現悲觀鎖樂觀鎖案例

django中實現事務的幾種方式

# 1 全局開啟事務---> 全局開啟事務,綁定的是http請求響應整個過程DATABASES = {'default': {#全局開啟事務,綁定的是http請求響應整個過程'ATOMIC_REQUESTS': True, }}from django.db import transaction# 局部禁用事務@transaction.non_atomic_requestsdef seckill(request):return HttpResponse('秒殺成功')# 2 一個視圖函數在一個事物中# fbv開啟from django.db import transaction@transaction.atomicdef seckill(request):return HttpResponse('秒殺成功')# cbv開啟from django.db import transactionfrom rest_framework.views import APIViewclass SeckillAPIView(APIView):@transaction.atomicdef post(self, request):pass# 3 局部使用事務
from django.db import transaction
def seckill(request):with transaction.atomic():pass  # 都在一個事物中return HttpResponse('秒殺成功')

事物的回滾和保存點


# 1 普通事務操作(手動操作)
transaction.atomic()  # 開啟事務
transaction.commit()  # 提交事務
transaction.rollback() # 回滾事務# 2 可以使用上下文管理器來控制(自動操作)
with transaction.atomic():  # 自動提交和回滾# 3 保存點-開啟事務干了點事設置保存點1干了點事設置一個保存點2干了點事回滾到干完第二個事,回滾到保存點2'''
在事務操作中,我們還會經常顯式地設置保存點(savepoint)
一旦發生異常或錯誤,我們使用savepoint_rollback方法讓程序回滾到指定的保存點
如果沒有問題,就使用savepoint_commit方法提交事務
'''from .models import Book
from django.db import transaction
def seckill(request):with transaction.atomic():# 設置回滾點,一定要開啟事務sid = transaction.savepoint()print(sid)try:book = Book.objects.get(pk=1)book.name = '紅樓夢'book.save()except Exception as e:# 如發生異常,回滾到指定地方transaction.savepoint_rollback(sid)print('出異常了,回滾')# 如果沒有異常,顯式地提交一次事務transaction.savepoint_commit(sid)return HttpResponse('秒殺成功')
transaction.atomic()  # 開啟事務
sid = transaction.savepoint() # 設置保存點
transaction.savepoint_rollback(sid) # 回滾到保存點
transaction.savepoint_commit(sid) #提交保存點

事務提交后,執行某個回調函數

# 有的時候我們希望當前事務提交后立即執行額外的任務,比如客戶下訂單后立即郵件通知賣家
###### 案例一##################
def send_email():print('發送郵件給賣家了')
def seckill(request):with transaction.atomic():# 設置回滾點,一定要開啟事務sid = transaction.savepoint()print(sid)try:book = Book.objects.get(pk=1)book.count = book.count-1book.save()except Exception as e:# 如發生異常,回滾到指定地方transaction.savepoint_rollback(sid)else:transaction.savepoint_commit(sid)#transaction.on_commit(send_email)transaction.on_commit(lambda: send_sms.delay('1898288322'))return HttpResponse('秒殺成功')##### 案例二:celery中使用###
transaction.on_commit(lambda: send_sms.delay('1898288322'))

django實現悲觀鎖樂觀鎖案例

# 線上賣圖書-圖書表  圖書名字,圖書價格,庫存字段-訂單表: 訂單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',}
}# 創建lqz數據庫

原生mysql悲觀鎖

begin; # 開啟事務select * from goods where id = 1 for update;  # 行鎖# order表中加數據update goods set stock = stock - 1 where id = 1; # 更新commit; #提交事務

orm實現上述

#1  使用悲觀鎖實現下單
@transaction.atomic  # 整個過程在一個事物中---》改兩個表:book表減庫存,訂單表生成記錄
def seckill(request):# 鎖住查詢到的book對象,直到事務結束sid = transaction.savepoint() # 保存點# 悲觀鎖: select_for_update()# 加鎖了--》行鎖還是表鎖? 分情況,都有可能#book = Book.objects.select_for_update().filter(pk=1).first()  # 加悲觀鎖,行鎖,鎖住當前行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-1book.save()transaction.savepoint_commit(sid)  # 提交,釋放行鎖return HttpResponse('秒殺成功')else:transaction.savepoint_rollback(sid) #回滾,釋放行鎖return HttpResponse('庫存不足,秒殺失敗')

樂觀鎖秒殺--》庫存還有,有的人就沒成功

# 2 樂觀鎖秒殺--普通版
@transaction.atomic
def seckill(request):# 鎖住查詢到的book對象,直到事務結束sid = transaction.savepoint()book = Book.objects.filter(pk=1).first()  # 沒加鎖count = book.countprint('現在的庫存為:%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('庫存不足,秒殺失敗')

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/38880.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/38880.shtml
英文地址,請注明出處:http://en.pswp.cn/news/38880.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Unity 鼠標控制 UI 放大、縮小、拖拽

文章目錄 1. 代碼2. 測試場景 1. 代碼 using UnityEngine; using UnityEngine.UI; using UnityEngine.EventSystems;public class UIDragZoom : MonoBehaviour, IDragHandler, IScrollHandler {private Vector2 originalSize;private Vector2 originalPosition;private RectTr…

css3 瀑布流布局遇見截斷下一列展示后半截現象

css3 瀑布流布局遇見截斷下一列展示后半截現象 注:css3實現瀑布流布局簡直不要太香~~~~~ 場景-在uniapp項目中 當瀑布流布局column-grap:10px 相鄰兩列之間的間隙為10px,column-count:2,2列展…

面試之快速學習C++11-完美轉發,nullptr, shared_ptr,unique_ptr,weak_ptr,shared_from_this

完美轉發及其實現 函數模版可以將自己的參數完美地轉發給內部調用的其他函數。所謂完美,即不僅能準確地轉發參數的值,還能保證被轉發參數的左右值屬性不變引用折疊:如果任一引用為左值引用,則結果為左值引用,否則為右…

在阿里云服務器上安裝Microsoft SharePoint 2016流程

本教程阿里云百科分享如何在阿里云ECS上搭建Microsoft SharePoint 2016。Microsoft SharePoint是Microsoft SharePoint Portal Server的簡稱。SharePoint Portal Server是一個門戶站點,使得企業能夠開發出智能的門戶站點。 目錄 背景信息 步驟一:添加…

【Leetcode 30天Pandas挑戰】學習記錄 下

題目列表: 數據統計:2082. The Number of Rich Customers1173. Immediate Food Delivery I1907. Count Salary Categories 數據分組1741. Find Total Time Spent by Each Employee511. Game Play Analysis I2356. Number of Unique Subjects Taught by Each Teacher…

無涯教程-Perl - setgrent函數

描述 此功能將枚舉設置(或重置)到組條目集的開頭。該函數應在第一次調用getgrent之前調用。 語法 以下是此函數的簡單語法- setgrent返回值 此函數不返回任何值。 例 以下是顯示其基本用法的示例代碼- #!/usr/bin/perl -wwhile( ($name,$passwd,$gid,$members)getgrent…

ide internal errors【bug】

ide internal errors【bug】 前言版權ide internal errors錯誤產生相關資源解決1解決2 設置虛擬內存最后 前言 2023-8-15 12:36:59 以下內容源自《【bug】》 僅供學習交流使用 版權 禁止其他平臺發布時刪除以下此話 本文首次發布于CSDN平臺 作者是CSDN日星月云 博客主頁是h…

C++模板的分離編譯問題

本文主要是了解一下為什么模板的定義和聲明不能分開,需要簡單了解一下編譯的四個階段。 一、理解編譯大致流程 整個編譯流程分為:預處理、編譯、匯編、鏈接,這里以源文件main.cpp文件為例。 預處理:對源文件進行宏替換、去注釋、…

CentOS8防火墻基礎操作應用

查看防火墻某個端口是否開放 firewall-cmd --query-port80/tcp 開放防火墻端口80 firewall-cmd --zonepublic --add-port80/tcp --permanent 關閉80端口 firewall-cmd --zonepublic --remove-port80/tcp --permanent 配置立即生效firewall-cmd --reload 查看防火墻狀態 s…

代碼隨想錄算法訓練營第58天|動態規劃part15|392.判斷子序列、115.不同的子序列

代碼隨想錄算法訓練營第58天|動態規劃part15|392.判斷子序列、115.不同的子序列 392.判斷子序列 392.判斷子序列 思路: (這道題也可以用雙指針的思路來實現,時間復雜度也是O(n)) 這道題應該算是編輯距…

[Android 11]使用Android Studio調試系統應用之Settings移植(七):演示用AS編譯錯誤問題

文章目錄 1. 篇頭語2. 系列文章3. AS IDE的配置3.1 AS版本3.2 Gradle JDK 版本4. JDK的下載5. AS演示工程地址6.其他版本JDK導致的錯誤1. 篇頭語 距離2021年開始,系列文章發表已經有近兩年了,依舊有網友反饋一些gitee上演示源碼編譯的一些問題,這里就記錄一下。 2. 系列文章…

uniApp引入vant2

uniApp引入vant2 1、cnpm 下載:cnpm i vantlatest-v2 -S2、main.js文件引入 import Vant from ./node_modules/vant/lib/vant;Vue.use(Vant);3.app.vue中引入vant 樣式文件 import /node_modules/vant/lib/index.css;

tomcat服務七層搭建動態頁面查看

一個服務器多實例復制完成 配置tomcat多實例的環境變量 vim /etc/profile.d/tomcat.sh配置tomcat1和tomcat2的環境變量 進入tomcat1修改配置 測試通信端口是否正常 連接正常 toncat 2 配置修改 修改這三個 端口配置修改完成 修改tomcat1 shudown 分別把啟動文件指向tomcat1…

數據結構--最短路徑 Dijkstra算法

數據結構–最短路徑 Dijkstra算法 Dijkstra算法 計算 b e g i n 點到各個點的最短路 \color{red}計算\ begin\ 點到各個點的最短路 計算 begin 點到各個點的最短路 如果是無向圖,可以先把無向圖轉化成有向圖 我們需要2個數組 final[] (標記各頂點是否已…

【ARM 嵌入式 編譯系列 10.1 -- GCC 編譯縮減可執行文件 elf 文件大小】

文章目錄 上篇文章:ARM 嵌入式 編譯系列 10 – GCC 編譯縮減可執行文件 elf 文件大小 接著上篇文章 ARM 嵌入式 編譯系列 10 – GCC 編譯縮減可執行文件 elf 文件大小 的介紹,我們看下如何進一步縮小可執行文件test的大小。上篇文章通過 strip --strip-…

RunnerGo的相比較JMeter優勢,能不能替代?

目前在性能測試領域市場jmeter占有率是非常高的,主要原因是相對比其他性能測試工具使用更簡單(開源、易擴展),功能更強大(滿足多種協議的接口),但是隨著研發協同的升級,平臺化的性能…

進程的概念和特征

進程的概念和特征 進程的概念進程的特征 進程的概念 在多道程序環境下,允許多個程序并發執行,此時他們將失去封閉性,并具有間斷性及不可再現性的特征。為此引入了進程(process)的概念,以便更好的描述和控制…

【Java】常用工具——異常

1. try-catch-finnaly try必須和catch或者finally組合使用; public class TryDemoOne {public static void main(String[] args) {Scanner input new Scanner(System.in);System.out.println("輸入第1個整數:");int one input.nextInt();S…

主流的嵌入式微處理器

目前主流的嵌入式微處理器系列有: ARM系列 MIPS系列 PowerPC系列 Super H系列 一、MPC/PPC系列 PowerPC(簡稱PPC),其基本設計源自IBM的POWER.1991年,APPLE(蘋果電腦)、IBM、Motorola(摩托羅拉)組成的AIM聯盟發展出Power微處理器…

mybatis-plus 根據指定字段 批量 刪除/修改

mybatis-plus 提供了根據id批量更新和修改的方法,這個大家都不陌生 但是當表沒有id的時候怎么辦 方案一: 手寫SQL方案二: 手動獲取SqlSessionTemplate 就是把mybatis plus 干的事自己干了方案三 : 重寫 executeBatch 方法結論: mybatis-plus 提供了根據id批量更新和修改的方法,…