MySQL高階知識點(一)事務的并發問題和隔離級別

簡單來說,事務就是要保證一組數據庫操作,要么全部成功,要么全部失敗。

在 MySQL 中,事務支持是在引擎層實現的。

MySQL 是一個支持多引擎的系統,但并不是所有的引擎都支持事務。

如 MySQL 原生的 MyISAM 引擎就不支持事務,這也是 MyISAM 被 InnoDB 取代的重要原因之一。

事務的四大特性(ACID)

  • 原子性: 事務是最小的執行單位,不允許分割。事務的原子性確保動作要么全部完成,要么完全不起作用;

  • 一致性: 執行事務前后,數據保持一致,例如轉賬業務中,無論事務是否成功,轉賬者和收款人的總額應該是不變的;

  • 隔離性: 并發訪問數據庫時,一個用戶的事務不被其他事務所干擾,各并發事務之間數據庫是獨立的;

  • 持久性: 一個事務被提交之后。它對數據庫中數據的改變是持久的,即使數據庫發生故障也不應該對其有任何影響

事務的并發問題

  • 臟讀(Dirty read): 當一個事務正在訪問數據并且對數據進行了修改,而這種修改還沒有提交到數據庫中,這時另外一個事務也訪問了這個數據,然后使用了這個數據。因為這個數據是還沒有提交的數據,那么另外一個事務讀到的這個數據是“臟數據”,依據“臟數據”所做的操作可能是不正確的。

  • 丟失修改(Lost to modify): 指在一個事務讀取一個數據時,另外一個事務也訪問了該數據,那么在第一個事務中修改了這個數據后,第二個事務也修改了這個數據。這樣第一個事務內的修改結果就被丟失,因此稱為丟失修改。 例如:事務1讀取某表中的數據A=20,事務2也讀取A=20,事務1修改A=A-1,事務2也修改A=A-1,最終結果A=19,事務1的修改被丟失。

  • 不可重復讀(Unrepeatableread): 指在一個事務內多次讀同一數據。在這個事務還沒有結束時,另一個事務也訪問該數據。那么,在第一個事務中的兩次讀數據之間,由于第二個事務的修改導致第一個事務兩次讀取的數據可能不太一樣。這就發生了在一個事務內兩次讀到的數據是不一樣的情況,因此稱為不可重復讀。

  • 幻讀(Phantom read): 幻讀與不可重復讀類似。它發生在一個事務(T1)讀取了幾行數據,接著另一個并發事務(T2)插入了一些數據時。在隨后的查詢中,第一個事務(T1)就會發現多了一些原本不存在的記錄,就好像發生了幻覺一樣,所以稱為幻讀。

不可重復度和幻讀區別:

不可重復讀的重點是修改,針對的數據是多行。
幻讀的重點在于新增或者刪除,針對數據是多行。

事務的隔離級別

SQL 標準定義了四個隔離級別:

  • READ-UNCOMMITTED(讀取未提交): 最低的隔離級別,允許讀取尚未提交的數據變更,可能會導致臟讀、幻讀或不可重復讀。
  • READ-COMMITTED(讀取已提交): 允許讀取并發事務已經提交的數據,可以阻止臟讀,但是幻讀或不可重復讀仍有可能發生。
  • REPEATABLE-READ(可重復讀): 對同一字段的多次讀取結果都是一致的,除非數據是被本身事務自己所修改,可以阻止臟讀和不可重復讀,但幻讀仍有可能發生。
  • SERIALIZABLE(可串行化): 最高的隔離級別,完全服從ACID的隔離級別。所有的事務依次逐個執行,這樣事務之間就完全不可能產生干擾,也就是說,該級別可以防止臟讀、不可重復讀以及幻讀。

MySQL InnoDB 存儲引擎的默認支持的隔離級別是 REPEATABLE-READ(可重讀,RR),
Oracle和sql server的默認隔離級別是READ-COMMITTED(讀取已提交,RC)。

我們可以通過

SELECT @@tx_isolation;

命令來查看,MySQL 8.0 該命令改為

SELECT @@transaction_isolation;

MySQL InnoDB 的 REPEATABLE-READ(可重讀)并不保證避免幻讀,需要應用使用加鎖讀來保證。
而這個加鎖度使用到的機制就是 Next-Key Locks。

因為隔離級別越低,事務請求的鎖越少,所以大部分數據庫系統的隔離級別都是 READ-COMMITTED(讀取提交內容) ,但是你要知道的是 InnoDB 存儲引擎默認使用 REPEATABLE-READ(可重讀,RR) 并不會有任何性能損失

事務隔離的實現

在實現上,數據庫里面會創建一個視圖,訪問的時候以視圖的邏輯結果為準。

  • 在“可重復讀”隔離級別下,這個視圖是在事務啟動時創建的,整個事務存在期間都用這個視圖。
  • 在“讀提交”隔離級別下,這個視圖是在每個 SQL 語句開始執行的時候創建的。
  • 這里需要注意的是,“讀未提交”隔離級別下直接返回記錄上的最新值,沒有視圖概念;
  • 而“串行化”隔離級別下直接用加鎖的方式來避免并行訪問。

每條記錄在更新的時候都會同時記錄一條回滾操作。
同一條記錄在系統中可以存在多個版本,這就是數據庫的多版本并發控制(MVCC)

回滾日志什么時候刪除?

系統會判斷當沒有事務需要用到這些回滾日志的時候,回滾日志會被刪除。

什么時候不需要了?

當系統里么有比這個回滾日志更早的read-view的時候。

為什么盡量不要使用長事務?

長事務意味著系統里面會存在很老的事務視圖,在這個事務提交之前,回滾記錄都要保留,這會導致大量占用存儲空間
除此之外,長事務還占用鎖資源,可能會拖垮庫。

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

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

相關文章

MBR400100CT-ASEMI肖特基模塊MBR400100CT

編輯:ll MBR400100CT-ASEMI肖特基模塊MBR400100CT 型號:MBR400100CT 品牌:ASEMI 封裝:M2 正向電流:400A 反向電壓:100V 引線數量:2 芯片個數:2 芯片尺寸:102MIL…

Django 初級指南:創建你的第一個 Django 項目

Django 是一個強大的 Python Web 框架,它采用了“模型-視圖-控制器”(MVC)的設計模式,能夠幫助開發者快速、簡潔地創建高質量的 Web 應用。這篇文章將引導你創建你的第一個 Django 項目。 一、安裝 Django 首先,你需…

OpenCV-Python中的圖像處理-霍夫變換

OpenCV-Python中的圖像處理-霍夫變換 霍夫變換霍夫直線變換霍夫圓環變換 霍夫變換 霍夫(Hough)變換在檢測各種形狀的技術中非常流行,如果要檢測的形狀可以用數學表達式描述,就可以是使用霍夫變換檢測它。即使要檢測的形狀存在一點破壞或者扭曲也是可以使…

【1day】復現大華智慧園區綜合管理平臺SQL注入漏洞

目錄 一、漏洞描述 二、影響版本 三、資產測繪 四、漏洞復現 一、漏洞描述 大華智慧園區綜合管理平臺是一個集智能化、信息化、網絡化、安全化為一體的智慧園區管理平臺,旨在為園區提供一站式解決方案,包括安防、能源管理、環境監測、人員管理、停車管理等多個方面。大華…

【C/C++】關于C++構造函數成員初始化

文章目錄 1. 第一種方式2. 第二種方式3. 優劣 1. 第一種方式 成員初始化列表。在構造函數的參數列表后使用冒號分割的一組初始化語句。 class my_class { public:my_class(int a, int b): m_x(a), m_y(b) {/*....*/} private:int m_x;int m_y; };2. 第二種方式 在構造函數內…

【skynet】skynet 服務間通信

寫在前面 skynet 服務之間有自己的一套高效通信 API 。本文給出簡單的示例。 文章目錄 寫在前面準備工作編寫代碼運行結果 準備工作 首先要有一個編譯好,而且工作正常的 skynet 。 編寫代碼 在 skynet/example 目錄編寫一個配置文件,兩個代碼文件。 …

(7)(7.1) 使用航點和事件規劃任務

文章目錄 前言 7.1.1 設置Home位置 7.1.2 視頻:制作并保存多路點任務 7.1.3 視頻:加載已保存的多航點任務 7.1.4 使用說明 7.1.5 提示 7.1.6 自動網格 7.1.7 任務指令 7.1.8 任務結束 7.1.9 任務重置 7.1.10 MIS_OPTIONS 7.1.11 任務再出發 …

renderdoc源碼分析(四) 重放

//TODO 先貼下飛書文檔,后續找時間再整理到這 Docs

04 - 分離頭指針情況、理解HEAD和branch

查看所有文章鏈接:(更新中)GIT常用場景- 目錄 文章目錄 1. 分離頭指針2. HEAD和branch2.1 branch的一些操作2.2 HEAD 1. 分離頭指針 分離頭指針detached HEAD是一種HEAD指針指向了某一個具體的 commit id,而不是分支的情況。 切換…

springboot 使用zookeeper實現分布式ID

添加ZooKeeper依賴&#xff1a;在pom.xml文件中添加ZooKeeper客戶端的依賴項。例如&#xff0c;可以使用Apache Curator作為ZooKeeper客戶端庫&#xff1a; <dependency><groupId>org.apache.curator</groupId><artifactId>curator-framework</arti…

Faiss在windows下安裝和使用

pip install faiss-cpu 直接安裝可能出現問題&#xff1a; error: command swig.exe failed: No such file or directory 安裝swig即可解決&#xff0c;安裝方式

學習Vue:Event Bus 與 Provide/Inject

在Vue.js中&#xff0c;兄弟組件通信是指兩個沒有直接父子關系的組件之間如何進行數據傳遞和通信。為了實現兄弟組件通信&#xff0c;我們可以借助Vue的一些特性&#xff0c;如Event Bus和Provide/Inject。讓我們一起來深入了解這些方法&#xff0c;并通過實例來看看如何實現兄…

服務器如何防止cc攻擊

對于搭載網站運行的服務器來說&#xff0c;cc攻擊應該并不陌生&#xff0c;特別是cc攻擊的攻擊門檻非常低&#xff0c;有個代理IP工具&#xff0c;有個cc攻擊軟件就可以輕易對任何網站發起攻擊&#xff0c;那么服務器如何防止cc攻擊?請看下面的介紹。 服務器如何防止cc攻擊&a…

希爾排序【Java算法】

文章目錄 1. 概念2. 思路3. 代碼實現 1. 概念 希爾排序也是一種插入排序&#xff0c;它是簡單插入排序經過改進之后的一個更高效的版本&#xff0c;也稱為縮小增量排序。希爾排序在數組中采用跳躍式分組的策略&#xff0c;通過某個增量將數組元素劃分為若干組&#xff0c;然后分…

iOS學習—制作全局遮罩

在.h文件中線聲明show()方法 - (void)show; .m文件中添加全屏遮罩&#xff0c;在遮罩上添加了一個選擇框并添加了底部彈出的動畫&#xff0c;可自行在其中添加tableview、pickerview等其他視圖&#xff0c;并添加了點擊選擇框視圖外區域隱藏 #import "MaskView.h"…

Java:PO、VO、BO、DO、DAO、DTO、POJO

&#x1f497;wei_shuo的個人主頁 &#x1f4ab;wei_shuo的學習社區 &#x1f310;Hello World &#xff01; Java&#xff1a;PO、VO、BO、DO、DAO、DTO、POJO PO持久化對象&#xff08;Persistent Object&#xff09; PO是持久化對象&#xff0c;用于表示數據庫中的實體或表…

tauri-vue:快速開發跨平臺軟件的架子,支持自定義頭部UI拖拽移動和窗口陰影效果

Tauri Vue Typescript 一個使用 taurivuets 開發跨平臺軟件的模板&#xff0c;支持窗口頭部自定義 UI 和拖拽和窗口陰影&#xff0c;不用再自己做適配了&#xff0c;拿來即用&#xff0c;非常 nice。而且已經封裝好了 tauri 的 http 請求工具&#xff0c;省去很多彎路。開源…

分布式 - 消息隊列Kafka:Kafka消費者分區再均衡(Rebalance)

文章目錄 01. Kafka 消費者分區再均衡是什么&#xff1f;02. Kafka 消費者分區再均衡的觸發條件&#xff1f;03. Kafka 消費者分區再均衡的過程&#xff1f;04. Kafka 如何判定消費者已經死亡&#xff1f;05. Kafka 如何避免消費者的分區再均衡?06. Kafka 消費者分區再均衡有什…

UglifyJS 和JShaman相比有什么不同?都可以進行js混淆加密嗎?

UglifyJS 和JShaman相比有什么不同&#xff1f; UglifyJS主要功能是壓縮JS代碼&#xff0c;減小代碼體積&#xff1b;JShaman是專門用于對JS代碼混淆加密&#xff0c;目的是讓JS代碼變的不可讀、混淆功能邏輯、加密代碼中的隱秘數據或字符&#xff0c;是用于代碼保護的。 因此…

java.lang.NoClassDefFoundError: org/apache/tez/dag/api/TezConfiguration

錯誤&#xff1a; java.lang.NoClassDefFoundError: org/apache/tez/dag/api/TezConfigurationat org.apache.hadoop.hive.ql.exec.tez.TezSessionPoolSession$AbstractTriggerValidator.startTriggerValidator(TezSessionPoolSession.java:74)at org.apache.hadoop.hive.ql.e…