資料庫隔離級別

来源:https://www.cnblogs.com/moyuduo/archive/2020/04/05/12639482.html
-Advertisement-
Play Games

資料庫隔離級別 如果沒有隔離級別會出現的問題 臟讀 意思是讀取到了事務正在修改的數據,如果事務回滾,那麼拿到的數據就是錯誤的 | 時間 | 事務A | 事務B | | | | | | 1 | 開始事務 | | | 2 | 讀取quantity為5 | | | 3 | 修改quantity為4 | | ...


資料庫隔離級別

如果沒有隔離級別會出現的問題

臟讀

意思是讀取到了事務正在修改的數據,如果事務回滾,那麼拿到的數據就是錯誤的

時間 事務A 事務B
1 開始事務
2 讀取quantity為5
3 修改quantity為4
4 開始事務
5 讀取到quantity為4
6 發生錯誤,回滾,quantity為5
7 提交事務

在按照正常邏輯quantity應該為5

不可重覆讀

時間 事務A 事務B
1 開始事務
2 讀取quantity為5
3 開始事務
4 修改quantity為4
5 提交事務
6 讀取quantity為4
7 提交事務

在同一個事務內,兩次讀取同一個數據產生不一致

幻讀

時間 事務A 事務B
1 開始事務
2 更新所有行的quantity為100
3 開始事務
4 插入一行quantity為5
5 提交事務
6 查詢所有行的quantity
7 提交事務

當一個事務內更新所有行後,另一個事務插入了新行,當再次查看記錄時,發現有未更新的記錄,好像幻覺一樣

丟失更新

第一種情況:

時間 事務A 事務B
1 開始事務
2 查詢到quantity為10
3 開始事務
4 查詢到quantity為10
5 更新quantity為11
6 提交事務
7 更新quantity為9
8 事務回滾,quantity為10

可以看到,回滾的事務把正常事務的數據覆蓋了,正常事務的數據丟失了

第二種情況:

時間 事務A 事務B
1 開始事務
2 查詢到quantity為10
3 開始事務
4 查詢到quantity為10
5 更新quantity為9
6 提交事務
7 更新quantity為11
8 提交事務

這種情況是事務在執行期間,其他事務對數據進行了修改,那麼當前事務拿到的數據就是錯的,對錯的數據進行更新,那也就沒有意義了

解決方法

對於臟讀、不可重覆讀、幻讀

我們可以使用資料庫提供的隔離級別來避免以上情況

隔離級別 臟讀 不可重覆讀 幻讀
Read-Uncommitted(讀取未提交的內容)
Read-Committed(讀取已提交的內容) ×
Repeatable-Read(可重讀) × ×
Serializable(串列化) × × ×

Mysql的預設隔離級別為Repeatable-Read,可以通過以下命令查看

SELECT @@global.tx_isolation;--查看全局隔離級別
SELECT @@session.tx_isolation;--查看當前連接的隔離級別

修改隔離級別

SET @@global.tx_isolation='Read-Committed'
SET @@session.tx_isolation='Read-Committed'
--或
SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE

對於丟失更新

使用悲觀鎖

悲觀鎖主要有共用鎖(讀鎖)和排他鎖(寫鎖)

  • 共用鎖是指多個事務可以共用一個一把鎖,都可以讀取到數據,但是不能修改
  • 排他鎖就是一個事務獲得了排他鎖,那麼其他事務就不能獲得鎖(包括共用鎖和排他鎖),獲取排他鎖的事務可以對數據進行訪問和修改

Mysql預設開啟了自動事務提交,可以使用以下命令關閉

SET autocommit=0	--關閉自動事務提交

這裡必須要強調一下鎖的概念,不管是共用鎖還是排他鎖,都是我們給每一個數據元素加的,如果一個數據元素已經有了排他鎖,那麼久不能再給它加任何鎖,如果一個數據元素有共用鎖,那麼還可以給它加共用鎖,Mysql的InnoDB引擎預設給insert、update、delete都加了排他鎖,而select未加任何鎖

新建一個查詢視窗,開始事務,但是沒有提交,因為update預設給數據元素加排他鎖,所以這個時候我們去更新該數據元素就會出現

上一個事務還沒有提交,數據元素還有排他鎖,這個update語句要給數據元素加排他鎖,所以只有等待,這也驗證了update語句預設會給相關的數據元素加排他鎖

如果使用select語句加共用鎖進行查詢一樣會阻塞

但是使用select語句不加任何鎖是可以查出數據的,但是數據是更新之前的

所以,使用悲觀鎖在高併發情況下,對於減庫存這樣的操作,首先要使用排他鎖的select語句拿到庫存,如果已經有事務對這個數據元素上了鎖,那麼只有等待該事務釋放鎖,只有這樣拿到的庫存才是正確的

BEGIN;
DECLARE @now_quantity INT;
SELECT quantity INTO @now_quantity FROM item WHERE id=1 FOR UPDATE;//一定要加排他鎖
UPDATE item SET quantity=@now_quantity-1 WHERE id=1;
COMMIT;

而且需要註意,MySQL InnoDB預設行級鎖。行級鎖都是基於索引的,如果一條SQL語句用不到索引是不會使用行級鎖的,會使用表級鎖把整張表鎖住

使用悲觀鎖的方式解決丟失更新很簡單,但是也會帶來效率上的問題,如果一個事務上了鎖,那麼其他的都只有等待

使用樂觀鎖

我們可以給表中加上一個version自增的版本欄位,查詢的時候拿到版本欄位和庫存,當需要去更新的時候,如果版本不一致,那麼需要重新查詢,重覆上述步驟,知道拿到的版本和資料庫中的版本一致時,才進行更新,這樣就不需要等待,效率更高



您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 顯示目錄和文件的命令 Ls:用於查看所有文件夾的命令。 Dir:用於顯示指定文件夾和目錄的命令 Tree: 以樹狀圖列出目錄內容 Du:顯示目錄或文件大小 查找文件 locate a.txt :在系統全局範圍內查找文件名包含a.txt字樣的文件(比find快) find /home -mtime - ...
  • 本文主要是本人對 unix 操作系統中的數據緩衝區高速緩衝設計以及其演算法思路的一些理解,可能由於水平有限,文中難免會有錯誤,如若發現,懇請支持,謝謝! ...
  • SpringBoot系列(二)入門知識 往期推薦 "SpringBoot系列(一)idea新建springboot項目" 引言 本來新建springboot項目應該放在入門知識這一章的,但是由於新建springboot的第一篇文章只介紹了一種新建項目的方法,所以在這一章講解一下springboot的 ...
  • 因項目需要申請了新伺服器,故要重新配置環境。 nginx安裝: 一鍵安裝四個依賴: yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel 進入/usr/local/src目錄,創建nginx文件夾 cd /usr/lo ...
  • 良許在工作中,寫過一個 Shell 腳本,這個腳本可以從 4 個 NTP 伺服器輪流獲取時間,然後將最可靠的時間設置為系統時間。 因為我們對於時間的要求比較高,需要在短時間內就獲取到正確的時間。所以我們就需要對這個腳本運行時間進行測試,看看從開始運行到正確設置時間需要花費多少時間。 其實在工作中,還 ...
  • 1、命令基礎 1.1、命令操作語法 命令 [參數] [文件] 參數,可有可無 文件,可有可無 2、基礎命令 2.1、查看當前工作目錄 pwd print name of current/workin directory 列印 名字 或 工作 目錄 2.2、切換目錄 cd cd 目錄 相對路徑與絕對路 ...
  • [TOC] 1.集群架構 | 主機名 | 角色 | IP地址 | | : : | : : | : : | | hdss7 21.host.com | flannel | 10.4.7.21 | | hdss7 22.host.com | flannel | 10.4.7.22 | 部署方法以hdss ...
  • redis 實戰-redis 事務 1.描述 redis 事務單獨的隔離操作:事務中的所有命令都會序列化、按順序執行。事務在執行過程中,不會被其他客戶端發送過來的命令請求所打斷。 redis 事務沒有隔離級別的概念:隊列中的命令沒有提交之前都不會實際的被執行,因為事務提交前任何指令都不會被實際執行, ...
一周排行
    -Advertisement-
    Play Games
  • GoF之工廠模式 @目錄GoF之工廠模式每博一文案1. 簡單說明“23種設計模式”1.2 介紹工廠模式的三種形態1.3 簡單工廠模式(靜態工廠模式)1.3.1 簡單工廠模式的優缺點:1.4 工廠方法模式1.4.1 工廠方法模式的優缺點:1.5 抽象工廠模式1.6 抽象工廠模式的優缺點:2. 總結:3 ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 本章將和大家分享ES的數據同步方案和ES集群相關知識。廢話不多說,下麵我們直接進入主題。 一、ES數據同步 1、數據同步問題 Elasticsearch中的酒店數據來自於mysql資料庫,因此mysql數據發生改變時,Elasticsearch也必須跟著改變,這個就是Elasticsearch與my ...
  • 引言 在我們之前的文章中介紹過使用Bogus生成模擬測試數據,今天來講解一下功能更加強大自動生成測試數據的工具的庫"AutoFixture"。 什麼是AutoFixture? AutoFixture 是一個針對 .NET 的開源庫,旨在最大程度地減少單元測試中的“安排(Arrange)”階段,以提高 ...
  • 經過前面幾個部分學習,相信學過的同學已經能夠掌握 .NET Emit 這種中間語言,並能使得它來編寫一些應用,以提高程式的性能。隨著 IL 指令篇的結束,本系列也已經接近尾聲,在這接近結束的最後,會提供幾個可供直接使用的示例,以供大伙分析或使用在項目中。 ...
  • 當從不同來源導入Excel數據時,可能存在重覆的記錄。為了確保數據的準確性,通常需要刪除這些重覆的行。手動查找並刪除可能會非常耗費時間,而通過編程腳本則可以實現在短時間內處理大量數據。本文將提供一個使用C# 快速查找並刪除Excel重覆項的免費解決方案。 以下是實現步驟: 1. 首先安裝免費.NET ...
  • C++ 異常處理 C++ 異常處理機制允許程式在運行時處理錯誤或意外情況。它提供了捕獲和處理錯誤的一種結構化方式,使程式更加健壯和可靠。 異常處理的基本概念: 異常: 程式在運行時發生的錯誤或意外情況。 拋出異常: 使用 throw 關鍵字將異常傳遞給調用堆棧。 捕獲異常: 使用 try-catch ...
  • 優秀且經驗豐富的Java開發人員的特征之一是對API的廣泛瞭解,包括JDK和第三方庫。 我花了很多時間來學習API,尤其是在閱讀了Effective Java 3rd Edition之後 ,Joshua Bloch建議在Java 3rd Edition中使用現有的API進行開發,而不是為常見的東西編 ...
  • 框架 · 使用laravel框架,原因:tp的框架路由和orm沒有laravel好用 · 使用強制路由,方便介面多時,分多版本,分文件夾等操作 介面 · 介面開發註意欄位類型,欄位是int,查詢成功失敗都要返回int(對接java等強類型語言方便) · 查詢介面用GET、其他用POST 代碼 · 所 ...
  • 正文 下午找企業的人去鎮上做貸後。 車上聽同事跟那個司機對罵,火星子都快出來了。司機跟那同事更熟一些,連我在內一共就三個人,同事那一手指桑罵槐給我都聽愣了。司機也是老社會人了,馬上聽出來了,為那個無辜的企業經辦人辯護,實際上是為自己辯護。 “這個事情你不能怪企業。”“但他們總不能讓銀行的人全權負責, ...