MySQL事務隔離級別以及髒讀 幻讀 不可重複讀

2021-10-20 20:47:34 字數 2620 閱讀 2368

事務的隔離性

mysql是乙個客戶端/伺服器架構的軟體,對於同乙個伺服器來說,可以有若干個客戶端與之連線,每個客戶端與伺服器連線上之後,就可以稱之為乙個會話(session)。每個客戶端都可以在自己的會話中向伺服器發出請求語句,乙個請求語句可能是某個事務的一部分,也就是對於伺服器來說可能同時處理多個事務。當資料庫上有多個事務同時執行的時候,就可能出現髒讀(dirty read)、不可重複讀(non-repeatable read)、幻讀(phantom read)的問題,為了解決這些問題,就有了 「隔離級別」 的概念。

理論上在某個事務對某個資料進行訪問時,其他事務應該進行排隊,當該事務提交之後,其他事務才可以繼續訪問這個資料。但一般情況下隔離得越嚴實,效率就會越低。因此很多時候,我們都要在隔離性和效率二者之間尋找乙個平衡點。

事務併發執行遇到的問題

髒讀(dirty read): 髒讀是指乙個事務讀到了另乙個未提交事務修改過的資料。

如小王的賬戶中有100的餘額,接下來有兩個事務對小王的賬戶進行訪問。

sql標準制定的四種隔離級別

iso 和 anis sql 標準制定了四種事務隔離級別的標準,分別為:讀未提交(read uncommitted)、讀提交(read committed)、可重複讀(repeatable read)和序列化(serializable )。

我們先來看下這四種隔離級別的意思。

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

讀提交: 乙個事務提交之後,它做的變更才會被其他事務看到。

可重複讀: 乙個事務執行過程中看到的資料,總是跟這個事務在啟動時看到的資料是一致的。當然在可重複讀隔離級別下,未提交的變更對其他事務也是不可見的。

序列化: 顧名思義是對於同一行記錄,「寫」會加「寫鎖」,「讀」會加「讀鎖」。當出現讀寫鎖衝突的時候,後訪問的事務必須等前乙個事務執行完成,才能繼續執行。

sql 標準中規定,針對不同的隔離級別,併發事務可以發生不同嚴重程度的問題,具體情況如下:

( √ 表示可以發生;× 表示不可以發生)

mysql對四種隔離級別的支援情況

mysql innodb 儲存引擎支援4種隔離級別,但與 sql 標準中定義的不同的是,innodb 儲存引擎在預設的可重複讀(repeatable read)事務隔離級別下,使用 next-key lock 鎖的演算法,避免了幻讀的產生。也就是說 innodb 儲存引擎在可重複讀(repeatable read)的事務隔離級別下,已經可以完全保證事務的隔離性要求,即達到了 sql 標準中的序列化(serializable )隔離級別的要求。

如何設定事務的隔離級別

在 innodb 儲存引擎中,可以使用以下命令來設定全域性或者當前會話的事務隔離級別:

set

[global

|session

]transaction

isolation

level

如想設定當前會話的隔離級別為讀提交,可以使用如下語句:

set

session

transaction

isolation

level

read

committed

;

如果想在 mysql 資料庫啟動時就設定事務的預設隔離級別,那就需要修改配置檔案中 transaction-isolation 的值,比方說,我們在啟動前指定了 transaction-isolation = read committed,那麼事務的預設隔離級別就從原來的 repeatable read 變成了read committed。

檢視當前會話的事務隔離級別,可以用如下語句:

select @@transaction_isolation

;

檢視全域性的事務隔離級別,可以使用如下語句:

select @@global.transaction_isolation

;

注意:transaction_isolation 是在 mysql 5.7.20 的版本中引入來替換tx_isolation的,如果你使用的是之前版本的 mysql,請將上述用到的 transaction_isolation 的地方替換為 tx_isolation。

幻讀補充:

幻讀示例中,假如表有個主鍵id,查詢語句改為:select id from ***,如果會話a查詢出來有兩條資料(1,2)。期間會話b插入一條id為3的資料並且提交事務。會話a再次查詢資料依然是(1,2),但是當會話a要插入一條id為3的資料時,是插入不了的。這個現象應該也屬於幻讀現象吧?在序列化隔離級別下不會發生這種情況。

事務隔離級別 髒讀 spring 測試

建立乙個controller,寫兩個url,用於測試髒讀 一 testcontroller autowired private testservice testservice responsebody apiimplicitparams apioperation value listfordirty...

mysql 隔離級別 髒讀 測試

修改方 查詢方 session a b autocommit off not care 修改方是為了開啟事務 isolation not care read uncommited為邊界 執行順序 左側開啟一次會話 左側第一次insert 右側第一次select 自動提交會話 顯示讀到髒讀 左側rol...

事務隔離髒讀幻讀 mysql

先說什麼叫做 事務隔離 事務隔離是指多個事務同時在進行中 如果只有乙個事務,那就無所謂隔離不隔離了 時,各個事務被隔離開來,相互之間的影響和事物的隔離級別有關,按照 讀未提交 讀已提交 可重複讀 序列化 的順序,越往後面隔離級別越高,事務之間的影響越小。下面的內容都以這個資料表為例進行說明 idmo...