資料庫事務隔離級別

来源:https://www.cnblogs.com/qisi/archive/2023/06/09/transaction_isolation_level.html
-Advertisement-
Play Games

標準隔離級別 讀未提交、讀已提交、可重覆讀、串列化 串列化 對事務中所有讀寫的數據加上讀鎖、寫鎖、範圍鎖。所以衝突的事務必須同步執行。 //console1 start transaction ; select * from transaction_test where `key`=1; updat ...


標準隔離級別

讀未提交、讀已提交、可重覆讀、串列化

串列化

對事務中所有讀寫的數據加上讀鎖、寫鎖、範圍鎖。所以衝突的事務必須同步執行。
//console1
start transaction ;
select * from transaction_test where `key`=1;
update transaction_test set name='newTest' where `key`=1;
//console2
start transaction ;
select * from transaction_test where `key`=1;(由於事務1沒有釋放寫鎖,所以這裡的查詢會阻塞
如果等待時間過長,會報如下的錯誤;如果事務1只是查詢,那麼事務2也可以查詢)
[40001][1205] Lock wait timeout exceeded; try restarting transaction
//console1
commit ;(提交完之後如果事務2沒有等待超時,那麼會立即執行)
//console2;
commit ;

可重覆讀

核心是只對事務中所有讀寫的數據加上讀鎖、寫鎖,不加範圍鎖。 相比於讀已提交,由於對整個事務都加上了讀鎖,避免其他事務可以進行更新,進而保證同一個事務多次讀到的數據都是沒有被修改過的數據。
----避免可重覆讀----
name初始值為init
//console1
start transaction ;
select * from transaction_test where `key`=1;(查詢結果是init)
//console2
start transaction ;
update transaction_test set name='test' where `key`=1;
(理論上,由於事務1已經獲取了讀鎖,事務2這裡添加寫鎖應該是添加不上的,應該是阻塞中才對;
但是,實操發現,執行成功了,且在事務2中通過下麵這個語句查詢是test,這應該也是mvcc導致的
select * from transaction_test where `key`=1;
//console1
select * from transaction_test where `key`=1;
console1的第2次查詢,查詢結果和第一次一樣,還是init
另外,事務2都獲得寫鎖了,怎麼能允許你事務1再去獲得讀鎖
commit ;
//console2
commit ;
相比於串列化,由於沒有加範圍鎖,會引發一種叫幻讀的情況 所謂幻讀是指在同一個事務中,第一次查詢id<10的假定有1條,第二次查詢可能會有2條,原因是在兩次查詢的中間,存在別的事務插入或者刪除了數據,由於事務A只加了讀鎖或者寫鎖,只能防止其他事務對已經加鎖的這幾條數據進行修改,但避免不了插入和刪除,所以才會出現這個問題。
----幻讀----
初始是1,name
//console1
start transaction ;
select * from transaction_test where `key`<10;
//console2
start transaction ;
insert into transaction_test ( `key`,`name`) value (3,'newddd');
select * from transaction_test where `key`<10;
commit;
//console1
select * from transaction_test where `key`<10;
理論上來講,這個地方應該會查到三條,但是實操發現,在事務2添加並提交之後,事務1查到了依然是原來的樣子
commit ;
select * from transaction_test where `key`<10;(提交之後再次查詢就有新結果了)

讀已提交

核心是對事務中需要更新的操作行加寫鎖,直到事務結束,但對查詢的操作行加讀鎖,但在查詢完之後立即釋放,即不是在整個事務範圍鎖定。 讀已提交通過對查詢操作加鎖來避免讀未提交,在事務B修改數據時因為其在事務結束之前一直持有寫鎖,事務A無法對數據加讀鎖,只能等待事務B提交事務才可以讀取,這也是讀已提交的名稱的由來。 雖然解決了讀未提交的問題,但是由於只在查詢的時候短暫加了寫鎖,引發了另一個不可重覆讀的問題; 所謂不可重覆讀是指在同一個事務中,對於同樣一條數據的兩次查詢結果不一樣,那麼這個和幻讀有什麼區別呢?幻讀整個事務中都存在讀鎖或者寫鎖,其他事務無法修改,只能增刪;但是不可重覆讀,則是指當前已經查到的結果被更新了。 原因是假如同一個事務兩次查詢中間,別的事務進行了修改,由於事務A沒有加整個事務範圍的讀鎖,所以事務B是可以成功獲取寫鎖的,進而修改數據,最終導致了不可重覆讀。
---避免讀未提交----
name初始值是init
//console1
start transaction ;
select * from transaction_test where `key`=1;
update transaction_test set name='test' where `key`=1;
//console2
start transaction ;
select * from transaction_test where `key`=1;(由於讀不到未提交的,所以肯定獲取不到修改後的test值,理論上只能等待事務1結束)
這個地方由於事務1已經添加了寫鎖,原則上事務2根本查詢不了,應該阻塞,就像串列化那裡一樣
但是實際結果卻是可以查到以前的值,即init;所以這裡應該是mvcc的作用
在讀已提交的級別下,mvcc機制總是取最新的版本即可,即最近被 Commit 的那個版本的數據記錄。
這樣保證了讀到的都是已提交的事務,且保留了幻讀問題
最新版本的快照讀,不是當前讀
//console1
commit;//提交之後,事務2再次查詢,發現已經可以獲取到改動後的值了,即test

---不可重覆讀----
name初始值是init
//console1
start transaction ;
select * from transaction_test where `key`=1;(第一次查詢是init)
//console2
start transaction ;
update transaction_test set name='test' where `key`=1;(在事務2中更新並提交)
commit ;
//console1
select * from transaction_test where `key`=1;(第二次查詢是test)
commit ;

讀未提交

核心是對事務中需要更新的操作行加寫鎖,直到事務結束,但對查詢的操作行不加鎖。 引發的問題是臟讀,其實就是讀到了其他事務還沒有提交的數據;那麼為什麼事務A可以讀到事務B還沒有提交的數據? 分為兩步理解: 1.為什麼存在可以讀的新的數據? 核心原因應該是write-ahead logging的設計。即上一章提到的允許在事務提交之前提前寫入數據,理論上肯定是寫到了記憶體中,並且記錄到undolog裡面,雖然還不太情況事務的提交真正幹了什麼操作,但目前來,在記憶體是可以讀到已經修改好的數據。 2.為什麼可以讀到已經加了寫鎖的數據 原因是讀未提交讀取數據是不加讀鎖的,而寫鎖只能防止其他事物不能加讀鎖和寫鎖,而不能防止沒有鎖 也可以看一下這篇博客的解釋
show variables like 'transaction%';
set global transaction isolation level read uncommitted ;//設置完之後要重新登錄
CREATE TABLE `transaction_test` (
`key` int(11),
`name` varchar(10) DEFAULT NULL
) ENGINE=InnoDB;
---read uncommitted---
讀未提交
//console1
start transaction ;
insert into transaction_test value (1,'test');
//console2
start transaction ;
select * from transaction_test where `key`=1; (查詢結果為1,test)
//console1
commit ;
//console2
commit;

兩個事務都是寫事務,晚開啟的事務更新會阻塞
//console1
start transaction ;
update transaction_test set name='newTest' where `key`=1;
//console2
start transaction ;
update transaction_test set name='Test' where `key`=1;(會阻塞,一直在執行中)
//console1
commit ;(在事務1提交成功後,事務2的更新立馬就成功了)
//console2
commit;

參考資料:

12 | 本地事務如何實現隔離性?-極客時間 03 | 事務隔離:為什麼你改了我還看不見?-極客時間 讀未提交-為什麼事務沒提交就可以讀到別人修改的數據 - 秦一居 - 博客園  

本文來自博客園,作者:起司啊,轉載請註明原文鏈接:https://www.cnblogs.com/qisi/p/transaction_isolation_level.html


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

-Advertisement-
Play Games
更多相關文章
  • #! https://zhuanlan.zhihu.com/p/635569763 # Excel DDE Commands ## 連接參數 `Application`: `Excel` `Topic`: `System`: 整個應用。 [sheetname] 指定 worksheet。 我使用的是 ...
  • # 一個超級大的文件如何更快讀 問題起因 ![](https://img2023.cnblogs.com/blog/2415052/202306/2415052-20230608110517159-989018809.png) 一個有千萬的數據的txt文件如何發揮IO的全部性能更快的讀和寫。 ## ...
  • 為什麼選擇FFmpeg? 延遲低,參數可控,相關函數方便查詢,是選擇FFmpeg作為編解碼器最主要原因,如果是處理實時流,要求低延遲,最好選擇是FFmpeg。 如果需要用Opencv或者C#的Emgucv這種庫來處理視頻流,也多是用FFmpeg做編解碼然後再轉換圖像數據給Opencv去處理。用Ope ...
  • 經過前幾篇文章的講解,初步瞭解ASP.NET Core MVC項目創建,啟動運行,以及命名約定,創建控制器,視圖,模型,接收參數,傳遞數據ViewData,ViewBag,路由,頁面佈局,wwwroot和客戶端庫,Razor語法,EnityFrameworkCore與資料庫,HttpContext,... ...
  • 大家好,我是 god23bin。今天給大家帶來的是 Linux 命令系列,**每天只需一分鐘,記住一個 Linux 命令不成問題**。今天,我們要介紹的是一個常用且強大的命令:tar。 ...
  • 目錄 一、awk概念 二、awk的工作過程 三、awk字元 四、內置變數 五、getline 六、awk的精準篩選 七、例子演示 八、實驗演示 一、awk概念 1.概念:awk 是一個功能強大的編輯工具,逐行讀取輸入文本,主要作用於文件內容,AWK信息的讀入也是逐行指定的匹配模式進行查找, 對符合條 ...
  • 本篇首先介紹下EXTI的結構,接著介紹外部中斷的相關概念,對STM32的IO外部中斷EXTI有個初步的瞭解,在此基礎上重點圍繞IO外部中斷EXTI的使用展開分析。 ...
  • [TOC](【後端面經-資料庫】MySQL的存儲引擎簡介) # MySQL的存儲引擎 mysql主要有四類存儲引擎,目前主要使用InnoDB作為存儲引擎。 ## 0. 存儲引擎的查看和修改 - 查看當前資料庫的預設存儲引擎 ```sql show variables like 'default_st ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...