91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

MySQL中的事務隔離是什么意思

發布時間:2021-08-30 10:39:54 來源:億速云 閱讀:160 作者:chen 欄目:MySQL數據庫

本篇內容介紹了“MySQL中的事務隔離是什么意思”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

事務就是要保證一組數據庫操作,要么全部成功,要么全部失敗。在MySQL中,事務支持是在引擎層實現的,但并不是所有的引擎都支持事務。比如MySQL原生的MyISAM引擎就不支持事務。

一、事務的特性

  • 原子性:一個事務中的所有操作,要么全部完成,要么全部不完成,不會結束在中間某個環節。事務在執行過程中發生錯誤,會被回滾到事務開始前的狀態,就像這個事務從來沒有執行過一樣

  • 一致性:在事務開始之前和事務結束以后,數據庫的完整性沒有被破壞

  • 隔離性:數據庫允許多個并發事務同時對數據進行讀寫和修改的能力,隔離性可以防止多個事務并發執行時由于交叉執行而導致數據的不一致

  • 持久性:事務處理結束后,對數據的修改就是永久的,即便系統故障也不會丟失

二、隔離級別

1.當數據庫上有多個事務同時執行的時候,就可能出現臟讀、不可重復讀、幻讀的問題

  • 臟讀:B事務讀取到了A事務尚未提交的數據

  • 不可重復讀:一個事務讀取到了另一個事務中提交的update的數據

  • 幻讀/虛讀:一個事務讀取到了另一個事務中提交的insert的數據

2.事務的隔離級別包括:讀未提交、讀提交、可重復讀和串行化

  • 讀未提交:一個事務還沒提交時,它做的變更就能被別的事務看到

  • 讀提交:一個事務提交之后,它做的變更才會被其他事務看到(解決臟讀,Oracle默認的隔離級別)

  • 可重復讀:一個事務執行過程中看到的數據,總是跟這個事務在啟動時看到的數據是一致的,而且未提交變更對其他事務也是不可見的(解決臟讀和不可重復讀,MySQL默認的隔離級別)

  • 串行化:對于同一行記錄,寫會加寫鎖,讀會加讀鎖,當出現讀寫鎖沖突的時候,后訪問的事務必須等前一個事務執行完成,才能繼續執行(解決臟讀、不可重復讀和幻讀)

安全性依次提交,性能依次降低

3.假設數據表T中只有一列,其中一行的值為1

create table T(c int) engine=InnoDB;
insert into T(c) values(1);

下面是按照時間順序執行兩個事務的行為:

MySQL中的事務隔離是什么意思

  • 若隔離級別是讀未提交,則V1是2。這時候事務B雖然還沒提交,但是結果已經被A看到了。V2、V3都是2

  • 若隔離級別是讀提交,則V1是1,V2是2。事務B的更新在提交后才能被A看到。V3也是2

  • 若隔離級別是可重復讀,則V1、V2是1,V3是2。之所以V2是1,遵循的是事務在執行期間看到的數據前后必須是一致的

  • 若隔離級別是串行化,V1、V2值是1,V3是2

在實現上,數據庫里面會創建一個視圖,訪問的時候以視圖的邏輯結果為準。在可重復讀隔離級別下,這個視圖是在事務啟動時創建的,整個事務存在期間都用這個視圖。在讀提交隔離級別下,這個視圖是在每個SQL語句開始執行的時候創建的。讀未提交隔離級別下直接返回記錄上的最新值,沒有視圖概念;而串行化隔離級別下直接用加鎖的方式來避免并行訪問

三、事務隔離的實現(以可重復讀為例)

在MySQL中,每條記錄在更新的時候都會同時記錄一條回滾操作。記錄上的最新值,通過回滾操作,都可以得到前一個狀態的值

假設一個值從1被按順序改成了2、3、4,在回滾日志里面就會有類似下面的記錄

MySQL中的事務隔離是什么意思

當前值是4,但是在查詢這條記錄的時候,不同時刻啟動的事務會有不同的read-view。如圖中看到的,在視圖A、B、C里面,這一個記錄的值分別是1、2、4,同一條記錄在系統中可以存在多個版本,就是數據庫的多版本并發控制(MVCC)。對于read-viewA,要得到1,就必須將當前值一次執行圖中所有的回滾操作得到

即使現在有另外一個事務正在將4改成5,這個事務跟read-view A、B、C對應的事務是不會沖突的

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

四、事務啟動的方式

MySQL的事務啟動方式有以下幾種:

  • 顯示啟動事務語句,begin或start transaction。提交語句是commit,回滾語句是rollback

  • set autocommit=0,這個命令將這個線程的自動提交關掉。意味著如果只執行一個select語句,這個事務就啟動了,而且不會自動提交事務。這個事務持續存在直到主動執行commit或rollback語句,或者斷開連接

建議使用set autocommit=1,通過顯示語句的方式來啟動事務

可以在information_schema庫中的innodb_trx這個表中查詢長事務,如下語句查詢持續時間超過60s的事務

select * from information_schema.innodb_trx where TIME_TO_SEC(timediff(now(),trx_started))>60

五、事務隔離還是不隔離

下面是一個只有兩行的表的初始化語句:

mysql> CREATE TABLE `t` (
  `id` int(11) NOT NULL,
  `k` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;
insert into t(id, k) values(1,1),(2,2);

事務A、B、C的執行流程如下,采用可重復讀隔離級別
MySQL中的事務隔離是什么意思

begin/start transaction命令:不是一個事務的起點,在執行到它們之后的第一個操作InnoDB表的語句,事務才真正啟動,一致性視圖是在執行第一個快照讀語句時創建的

start transaction with consistent snapshot命令:馬上啟動一個事務,一致性視圖是在執行這條命令時創建的

按照上圖的流程執行,事務B查到的k的值是3,而事務A查到的k的值是1

1、快照在MVCC里是怎么工作的?

在可重復讀隔離級別下,事務啟動的時候拍了個快照。這個快照是基于整個庫的,那么這個快照是如何實現的?

InnoDB里面每個事務有一個唯一的事務ID,叫做transaction id。它在事務開始的時候向InnoDB的事務系統申請,是按申請順序嚴格遞增的

每行數據也都是有多個版本的。每次事務更新數據的時候,都會生成一個新的數據版本,并且把transaction id賦值給這個數據版本的事務ID,記作row trx_id。同時,舊的數據版本要保留,并且在新的數據版本中,能夠有信息可以直接拿到它。也就是說,數據表中的一行記錄,其實可能有多個版本,每個版本有自己的row trx_id

下圖是一個記錄被多個事務連續更新后的狀態:

MySQL中的事務隔離是什么意思

語句更新生成的undo log(回滾日志)就是上圖中的是哪個虛線箭頭,而V1、V2、V3并不是物理上真實存在的,而是每次需要的時候根據當前版本和undo log計算出來的。比如,需要V2的時候,就是通過V4依次執行U3、U2算出來的

按照可重復讀的定義,一個事務啟動的時候,能夠看到所以已經提交的事務結果。但是之后,這個事務執行期間,其他事務的更新對它不可見。在實現上,InnoDB為每個事務構造了一個數組,用來保存這個事務啟動瞬間,當前在啟動了但還沒提交的所有事務ID。數組里面事務ID的最小值記為低水位,當前系統里面已經創建過的事務ID的最大值加1記為高水位。這個視圖數組和高水位就組成了當前事務的一致性視圖。而數據的可見性規則,就是基于數據的row trx_id和這個一致性視圖的對比結果得到的

這個視圖數組把所有的row trx_id分成了幾種不同的情況

MySQL中的事務隔離是什么意思

對于當前事務的啟動瞬間來說,一個數據版本的row trx_id,有以下幾種可能:

1)如果落在綠色部分,表示這個版本是已提交的事務或者是當前事務自己生成的,這個數據是可見的

2)如果落在紅色部分,表示這個版本是由將來啟動的事務生成的,肯定不可見

3)如果落在黃色部分,那就包括兩種情況

  • 若row trx_id在數組中,表示這個版本是由還沒提交的事務生成的,不可見

  • 若row trx_id不在數組中,表示這個版本是已經提交了的事務生成的,可見

InnoDB利用了所有數據都有多個版本的這個特性,實現了秒級創建快照的能力

2、為什么事務A的查詢語句返回的結果是k=1?

假設:

1.事務A開始時,系統里面只有一個活躍事務ID是99

2.事務A、B、C的版本號分別是100、101、102

3.三個事務開始前,(1,1)這一行數據的row trx_id是90

這樣,事務A的是數組就是[99,100],事務B的視圖數組是[99,100,101],事務C的視圖數組是[99,100,101,102]

MySQL中的事務隔離是什么意思

從上圖中可以看到,第一個有效更新是事務C,從數據從(1,1)改成了(1,2)。這時候,這個數據的最新版本的row trx_id是102,而90這個版本已經成為了歷史版本

第二個有效更新是事務B,把數據從(1,2)改成了(1,3)。這時候,這個數據的最新版本是101,而102又成為了歷史版本

在事務A查詢的時候,其實事務B還沒提交,但是它生成的(1,3)這個版本已經變成當前版本了。但這個版本對事務A必須是不可見的,否則就變成臟讀了

現在事務A要讀數據了,它的視圖數組是[99,100]。讀數據都是從當前版本讀起的。所以,事務A查詢語句的讀數據流程是這樣的:

  • 找到(1,3)的時候,判斷出row trx_id=101,比高水位大,處于紅色區域,不可見

  • 接著,找到上一個歷史版本,一看row trx_id=102,比高水位大,處于紅色區域,不可見

  • 再往前找,終于找到了(1,1),它的row trx_id=90,比低水位小,處于綠色區域,可見

雖然期間這一行數據被修改過,但是事務A不論在什么時候查詢,看到這行數據的結果都是一致的,我們稱之為一致性讀

一個數據版本,對于一個事務視圖來說,除了自己的更新總是可見以外,有三種情況:

  • 版本未提交,不可見

  • 版本已提交,但是是在視圖創建后提交的,不可見

  • 版本已提交,而且是在視圖創建前提交的,可見

事務A的查詢語句的視圖數組是在事務A啟動的時候生成的,這時候:

  • (1,3)還沒提交,屬于情況1,不可見

  • (1,2)雖然提交了,但是是在視圖數組創建之后提交的,屬于情況2,不可見

  • (1,1)是在視圖數組創建之前提交的,可見

3、為什么事務B的查詢語句返回的結果是k=3?

MySQL中的事務隔離是什么意思

事務B要去更新數據的時候,就不能再在歷史版本上更新了,否則事務C的更新就丟失了。因此,事務B此時的set k=k+1是在(1,2)的基礎上進行的操作

更新數據都是先讀后寫的,而這個讀,只能讀當前的值,稱為當前讀。除了update語句外,select語句如果加鎖,也是當前讀

假設事務C不是馬上提交的,而是變成了下面的事務C’,會怎么樣?
MySQL中的事務隔離是什么意思
上圖中,事務C更新后沒有馬上提交,在它提交前,事務B的更新語句先發起了。雖然事務C還沒提交,但是(1,2)這個版本也已經生成了,并且是當前的最新版本

這時候涉及到了兩階段鎖協議,事務C沒提交,也就是說(1,2)這個版本上的寫鎖還沒釋放。而事務B是當前讀,必須要讀最新版本,而且必須加鎖,因此就被鎖住了,必須等到事務C釋放這個鎖,才能繼續它的當前讀

MySQL中的事務隔離是什么意思

七、事務的可重復讀的能力是怎么實現的?

可重復讀的核心就是一致性讀;而事務更新數據的時候,只能用當前讀。如果當前的記錄的行鎖被其他事務占用的話,就需要進入鎖等待

而讀提交的邏輯和可重復讀的邏輯類似,它們最主要的區別是:

  • 在可重復讀隔離級別下,只需要在事務開始的時候創建一致性視圖,之后事務里的其他查詢都共用這個一致性視圖

  • 在讀提交隔離級別下,每一個語句執行前都會重復算出一個新的視圖

“MySQL中的事務隔離是什么意思”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

临高县| 西畴县| 鄄城县| 河东区| 集贤县| 临安市| 长治县| 大荔县| 威海市| 鸡西市| 利川市| 西乌| 邵东县| 无极县| 全椒县| 玉树县| 武安市| 望奎县| 荥阳市| 淮滨县| 南丹县| 眉山市| 西宁市| 改则县| 渭源县| 丽江市| 兴安县| 弋阳县| 镇赉县| 轮台县| 吴堡县| 平顶山市| 梅河口市| 太仆寺旗| 武山县| 博野县| 阳山县| 奉化市| 新闻| 阳谷县| 淮北市|