事務隔離級別 可重複讀

2021-09-27 01:44:07 字數 2612 閱讀 2082

mysql [pom_5]> select @@global.tx_isolation;

+-----------------------+

| @@global.tx_isolation |

+-----------------------+

| repeatable-read |

+-----------------------+

如果事務隔離級別顯示repeatable-read,即是可重複讀。

在資料庫操作中,為了有效保證併發讀取資料的正確性,提出的事務隔離級別。我們的資料庫鎖,也是為了構建這些隔離級別存在的。

隔離級別

髒讀(dirty read)

不可重複讀(nonrepeatable read)

幻讀(phantom read)

未提交讀(read uncommitted)

可能可能

可能已提交讀(read committed)

不可能可能

可能可重複讀(repeatable read)不可

不可

可能

可序列化(serializable )

不可能不可能

不可能未提交讀(read uncommitted):允許髒讀,也就是可能讀取到其他會話中未提交事務修改的資料

提交讀(read committed):只能讀取到已經提交的資料。oracle等多數資料庫預設都是該級別 (不重複讀)

可重複讀(repeated read):可重複讀。在同乙個事務內的查詢都是事務開始時刻一致的,innodb預設級別。在sql標準中,該隔離級別消除了不可重複讀,但是還存在幻象讀

序列讀(serializable):完全序列化的讀,每次讀都需要獲得表級共享鎖,讀寫相互都會阻塞

在可重複讀中,該sql第一次讀取到資料後,就將這些資料加鎖(悲觀鎖),其它事務無法修改這些資料,就可以實現可重複讀了。但這種方法卻無法鎖住insert的資料,所以當事務a先前讀取了資料,或者修改了全部資料,事務b還是可以insert資料提交,這時事務a就會發現莫名其妙多了一條之前沒有的資料,這就是幻讀,不能通過行鎖來避免。需要serializable隔離級別 ,讀用讀鎖,寫用寫鎖,讀鎖和寫鎖互斥,這麼做可以有效的避免幻讀、不可重複讀、髒讀等問題,但會極大的降低資料庫的併發能力。

但是mysql、oracle、postgresql等成熟的資料庫,出於效能考慮,都是使用了以樂觀鎖為理論基礎的mvcc(多版本併發控制)來實現。

對相同db例項建立兩個連線:a和b,來測試select, select for update, update語句的生效情況

a先提交

b先提交

a先開啟事務b的update內容

a的update內容

a先開啟事務b的update內容

a的update內容

結果是誰最後提交,誰的結果生效

a使用select for update

a使用select for update

a使用update

a開啟事務,b不開啟b裡面的select for update和update被阻塞

b不受影響

b裡面的select for update和update被阻塞

a不開啟事務,b開啟b不受影響

b不受影響

b不受影響

a,b開啟事務b裡面的select for update和update被阻塞

b不受影響

b裡面的select for update和update被阻塞

a,b不開啟事務b不受影響

b不受影響

b不受影響

結果是只有使用begin顯式開啟事務時,使用select for update才會對資料加上行級鎖,對其他連線的的select for update(對select沒有影響)和update造成阻塞效果。

下面是a開啟事務,然後使用a使用select for update,接著b使用select for update/select,a執行updat,最後commit,觀察整個過程中b的查詢效果。

b使用select for update

b使用select

b開啟事務b裡面的select for update被阻塞,a提交後,b讀到的是a修改的內容

b不受a阻塞,讀到的仍是b事務開啟時的內容

b不開啟事務b裡面的select for update被阻塞,a提交後,b讀到的是a修改的內容

b不受a阻塞,讀到的資料在a提交後變化

a先執行select for update

a先執行update

b後執行select未阻塞

未阻塞b後執行select for update阻塞

阻塞b後執行update阻塞阻塞

MySQL事務隔離級別可重複讀測試

開啟rds,查詢當前的事務隔離級別select tx isolation查詢得到時候可重複讀,於是做了如下測試。可重複隔離級別的特點是,每個事務可以在乙個事務中可以反覆讀取資料,每次讀取到的資料都是相同的。在 高效能mysql 一書中,講到這種隔離級別很好的解決了髒讀問題,也就是讀取的資料都是事務開...

mysql中事務隔離級別可重複讀說明

mysql中innodb引擎預設為可重複讀的 repeatable read 修改隔離級別的方法,你可以在my.inf檔案的 mysqld 中配置 transaction isolation 使用者可以用set transaction語句改變單個會話或者所有新進連線的隔離級別。它的語法如下 set ...

可重複讀隔離級別裡的可能死鎖

在今天的文章裡我想談論下在可重複讀隔離級別 transaction isolation level repeatable read 裡,當你執行事務時可能引起的2類死鎖。當你使用可重複讀 repeatable read 隔離級別設定你的事務,sql server對讀取資料把持需要的共享鎖 share...