談談MySQL的事務隔離級別

来源:https://www.cnblogs.com/tpniu/archive/2018/01/12/8274989.html
-Advertisement-
Play Games

這篇文章能夠闡述清楚跟資料庫相關的四個概念:事務、資料庫讀現象、隔離級別、鎖機制 ...


這篇文章能夠闡述清楚跟資料庫相關的四個概念:事務、資料庫讀現象、隔離級別、鎖機制  

一、事務

先來看下百度百科對資料庫事務的定義:

  作為單個邏輯單元執行一系列操作,要麼完全執行,要麼完全不執行。事務處理可以確保除非事務性單元內的所有操作都成功完成,否則不會永久更新面向數據的資源。

事務有四個屬性,稱為ACID屬性:

1、原子性(Atomicity):事務是一個原子單位,要麼全部執行,要麼全部不執行。

2、一致性(Consistent):事務的開始和結束,數據都必須保持一致狀態。

3、隔離性(isolation):資料庫系統提供隔離機制,保證併發事務之間是互相不幹擾的。也就意味著事務處理過程中的中間狀態對其他的事務是透明的。

4、持久性(Durable):事務完成之後,對數據的修改是永久性的,即使出現系統故障也能夠保持。

事務是一系列SQL語句的集合,如果沒有事務,會出現什麼問題?或者說SQL只能一條一條的單個執行,會出現什麼問題?

這個很簡單,如果沒有事務,我們平時生活中的銀行轉賬就無法操作。

二、資料庫讀現象

  ACID屬性裡面有一個是隔離級別,即併發事務之間互相不幹擾。互相不幹擾只是一個終極狀態,且需要消耗巨大的性能。在我們實際應用過程中,是存在很大的灰度空間的:隔離級別有程度的區分。所以如果隔離程度控制的比較弱的話,就會產生臟讀不可重覆讀以及幻讀的現象。

1、臟讀

事務T1修改某個欄位的值,然後事務T2讀取該值,此後T1撤銷了對該欄位的更新,或者更新成另外的值才commit到資料庫中,這樣T2讀取的數據是無效的或者錯誤的。導致T2依據臟數據所做的操作也是錯誤的。

思聰同學中午去食堂吃飯,看到窗邊的座位被如花同學占有了,思聰認為這個座位已經被占有了,就轉身去找其他的座位。不料,如花同學起身離開了。事實是:如花並不是吃飯,而是臨時坐在那裡等她的約會對象,只是臨時小坐一會,並沒有真正“commit”。

2、不可重覆讀

在資料庫訪問中,一個事務範圍內的兩次相同的查詢卻返回了不同的數據。

事務T1讀取某一數據,事務T2讀取並修改了該數據,T1為了對讀取值進行驗證而重新讀取,卻發現得到了不同的結果。

思聰同學中午去食堂吃飯,看到窗邊的座位是空的,便屁顛屁顛的跑去打飯,回來後卻發現這個座位被如花同學搶去了。

3、幻讀

幻讀解決了不可重覆讀的問題,即在同一個事務範圍內,兩次相同的查詢結果是相同的。但是可以新增表中的數據記錄。

幻讀是指事務T1對錶中的數據進行修改,假設修改涉及了表中全部的數據行,同時第二個事務也修改這個表中的數據,這種修改是向表中插入一條新的數據。後面就會出現操作了T1事務的用戶發現表中還有沒有修改的數據行,仿佛出現了幻覺一樣。

思聰同學中午去食堂吃飯,看到窗邊的座位是空的,便屁顛屁顛的跑去打飯,回來後窗邊的座位還是空的,便很高興坐上去準備開始吃飯,這時候卻發現如花同學搬了一個小板凳坐在旁邊狼吞虎咽,思聰頓時沒有了胃口。

如果需要解決臟讀、不可重覆讀、幻讀等這些資料庫讀現象,就必須相應提高事務的隔離級別。但是資料庫的隔離級別越高,對應的併發能力就越弱,性能也就相應的越差,所以我們還需根據具體的應用場景去權衡。

三、事務隔離級別

1、未提交讀

事務的最低隔離級別,在這種隔離級別下,一個事務可以讀取另外一個事務未提交的數據。

資料庫鎖實現原理:

事務T在讀數據的時候並未對數據進行加鎖,事務T在修改數據的時候對數據增加行級共用鎖

T1在讀取數據時,T2可以對相同數據進行讀取、修改。因為T1沒有進行任何鎖操作;當T2對記錄進行修改時,T1再次讀取數據可以讀取到T2修改後的數據。因為T2對數據進行修改只增加了行級共用鎖,T1可以再增加共用讀鎖進行數據讀取(儘管T2沒有提交事務)

如上所述,這種隔離級別,會導致臟讀現象

2、已提交讀

在一個事務修改數據過程中,如果事務沒有進行提交,其他事務不能讀取該數據

資料庫鎖實現原理:

事務T在讀取數據時增加行級共用鎖,讀取一旦結束,立即釋放;事務T在修改數據時增加行級排他鎖,直到事務結束才釋放。

T1在讀取數據的過程中,T2也可以對相同數據進行讀取,但是不能進行修改(T1增加的是共用鎖,T2也可以增加共用鎖,但是不能增加排他鎖)。T1讀取結束後,會立即釋放共用鎖,這時T2可以增加排他鎖,對數據進行修改,而此時T1既不能對數據進行讀取也不能進行修改,直到T2事務結束。

如上所述,這種隔離級別,解決了臟讀問題,但是不能解決不可重覆讀現象。

3、可重覆讀

事務T在數據讀取時,必須增加行級共用鎖,直到事務結束;事務T在修改數據過程中,必須增加行級排他鎖,直到數據結束。

資料庫鎖實現原理:

T1在讀取數據的過程中,T2也可以對相同數據進行讀取,但是不能進行修改(T1增加的是共用鎖,T2也可以增加共用鎖,但是不能增加排他鎖)。直到T1事務結束後,才會釋放共用鎖,這時T2才可以增加排他鎖,對數據進行修改。

如上所述,這種隔離級別,解決了不可重覆讀現象,但是這種隔離級別解決不了幻讀的問題:

T1進行查詢,讀取了10條記錄,並對十條記錄增加了行級鎖,此時T2是無法對這10行數據進行修改操作的,但是由於沒有表級鎖,它可以增加一條滿足T1查詢條件的記錄。隨後T1在進行查詢時,會發現雖然10條記錄沒有改變,但是突然多了一條記錄。

4、序列化

產生幻讀是由於沒有進行範圍查詢時沒有增加範圍鎖。

資料庫鎖實現原理:

 事務T在讀取數據時,必須先增加表級共用鎖,直到事務結束才釋放;事務T在修改數據時,必須先增加表級排他鎖,直到事務結束才釋放。

T1在讀取A表時,增加了表級共用鎖,此時T2也可以讀取A表,但是不能進行任何數據的修改,直到T1事務結束。隨後T2可以增加對A表的表級排他鎖,此時T1不能讀取A表中的任何數據,更不能進行修改。

如上所述,可序列化解決了臟讀、不可重覆讀、幻讀等讀現象,但是隔離級別越來越高的同時,在併發性上也就越來越低。

四、事務操作實踐 

預設情況下,MYSQL是自動提交的,也就意味著平時我們執行一條update語句時,MYSQL是自動幫我們提交的,儘快我們沒有顯示執行commit命令。但是這種只適用於單條SQL的執行。

如果我們想要同時執行多條SQL,並且執行過程中有SQL執行異常,需要回滾前面已經成功執行的SQL或者最終想回滾全部,則必須顯示的使用事務。

  1. 開始一項事務:start tr ansaction或者begin;

  2. 提交事務:commit;

  3. 回滾事務:rollback;

  4. 事務提交之後的操作:chain;

  5. 事務回滾之後的操作:release;

  6. 修改當前連接的提交方式:set autocommit;如果設置了set autocommit=0,則設置之後所有的事務都需要顯式的通過命令來進行提交或者回滾。

查詢當前會話的事務隔離級別

images/2pyKrnNwf5pC2F3eBa8A8K3DzBZ2azxA.png

查詢當前系統的事務隔離級別

images/DZYPrwHrsK5x5dK4STHQceX2h6iSNDd3.png

修改當前會話的事務隔離級別

images/7Yr4k8krs5naMHn3TciejMjmdxBWRNmH.png

提交讀演示

客戶端A 開啟事務,並更新數據

images/CtxNtjBJCaPHHK3PmxX4xYydWcenNkZY.png

此時事務還沒有提交,開啟客戶端B,併進行查詢,此時的數據還是未更新前的

images/2B5FcAmzZ3JWHJs2hX3ZT5WRKDA7DRkN.png

客戶端A進行事務提交,然後客戶端B查詢,此時是最新的數據

images/3ftrb2wN2Yn8Db3AYwBHxd5JmQJsHSap.png

commit and chain的演示

如果在提交的時候使用commit and chain,那麼在提交後立即開始一個新的事務

images/R5GMDSkjiZRWx4DmcZ7zQ74TQMn8HKex.png

A提交事務後,B再進行查詢

images/3kzdQD32SbywQWxffJBScSWR6wRPxwys.png

開啟事務會隱式解鎖

鎖表期間,用start transaction 命令開始一個新事務,則會隱式的執行unlock tables

A對錶進行寫鎖操作

images/ZKzxAfyfAHfT5Z823rHirYamFRMbhMJQ.png

此時B進行查詢:由於被A鎖表,所以查詢被阻塞

images/yWSc7PWzPSJTNwBBB8D4ZwbCFeYyK5JT.png

A開啟一個事務

images/73kdSd5QfJRJa7XtsaH7bkictpYGf3Hm.png

由於A開啟事務,隱式的釋放了寫鎖,所以B的查詢不再被阻塞

images/5KnEJPYmXTE6TNF2ytyDnf4TspXRmAfr.png

SAVEPOINT的使用

事務中可以通過定義SAVEPOINT,指定回滾事務的一個部分
A開啟事務並insert一條記錄,並設置savepoint

images/8KnAAhkGr5aH8bh2k28ySfH7PemQZEyc.png

B進行查詢,查詢到的是開啟事務前的數據

images/JyWNj2fPb6iEbbdzcTi6bQr8mBfE6zt8.png

A又插入一條數據,然後回滾到savepoint

images/QsjcpfTa3zy6math65hXSd8hHfE6dbSY.png

images/tfDMCMA4CP4ijB6f7BCd4FN7yhGhtSZY.png

B進行查詢

images/tx2tJmcCRzbBf8Pyp5n6NMkSmGyXmBC8.png

作者:冬瓜蔡
原文:http://www.cnblogs.com/dongguacai/p/7114885.html

更多Mysql參考內容:http://www.roncoo.com/article/index?tn=Mysql


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

-Advertisement-
Play Games
更多相關文章
  • 操作系統 : CentOS7.3.1611_x64 go語言版本:1.8.3 linux/amd64 InfluxDB版本:1.1.0 influxdb預設配置: meta預設配置: dir meta數據存放目錄,預設值:/var/lib/influxdb/meta meta數據文件預設路徑:/va ...
  • 1、首先要準備好安裝文件oracle11 2、在oracle11文件夾中找到setup.exe,雙擊運行 3、在配置安全更新中,輸入常用的電子郵件(非必填) 4、點擊下一步進入到“安裝選項“,預設選擇創建和配置資料庫 5、點擊”下一步“,選擇”伺服器類“ 6、點擊”下一步“,不進行任何修改 7、點擊 ...
  • mysql命令不區分大小寫。內容,表名什麼的是區分大小寫的。 語句以(;)結束。(\c)結束不想執行正在輸入的命令。(命令+ \G;)查看詳細結構 啟動/停止/重啟:server mysql start/stop/restart /etc/init.d/mysql start/stop/restar ...
  • IF OBJECT_ID('fn_GetChnNum') IS NOT NULL BEGIN DROP FUNCTION dbo.fn_GetChnNum; END; GO CREATE FUNCTION fn_GetChnNum ( @Number AS BIGINT )RETURNS VARCH ...
  • 1.應用場景和特點 hbase => 當數據量非常大的時候才會體現出hbase的優勢 特點: 海量數據存儲 => 單表可有上百億行。上百萬的列。也就是對列沒有限制。 => 關係型資料庫正常單表不超過五百萬行,不超過三十列。 面向列 => 動態添加數據的時候生成列。單獨對列進行各種操作。 多版本 稀疏 ...
  • 資料庫中left join,right join,inner join的差異 ...
  • 一 所需軟體:Redis、Ruby語言運行環境、Redis的Ruby驅動redis-xxxx.gem、創建Redis集群的工具redis-trib.rb 二 安裝配置redis redis下載地址 https://github.com/MSOpenTech/redis/releases ; 下載Re ...
  • mysql資料庫常用的時間類型有timestamp和datetime,兩者主要區別是占用存儲空間長度不一致、可存儲的時間也有限制,但針對不同版本下,timestamp欄位類型的設置需要慎重,因為不註意的可能會被“坑死”。 一、TIMESTAMP和DATETIME欄位類型對比 1.timestamp註 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...