MySQL 事務的隔離級別

2021-08-03 02:47:45 字數 4081 閱讀 8421

在標準的sql中事務的隔離級別一共有四種。事務的隔離級別主要定義了乙個事務做出的修改在別的事務中的可見性情況。事務的隔離級別越高通常開銷越低,同時併發程度也越高。事務的隔離級別在不同的儲存引擎中的實現也是不盡相同的,這裡只簡單介紹四種標準的隔離級別。(本文很多摘抄自《mysql》第三版)

四種標準的隔離級別分別為:read uncommitted(未提交讀),read committed(提交讀),repeatable read(可重複讀),serializable(可序列化)。

read uncommitted(未提交讀):

在乙個事務中的修改,即使沒有提交,對其他事務也是可見的。事務可以讀取未提交的資料----髒讀(dirty read),這個級別會導致很多的問題,並且從效能上講也不會比其他的級別好很多,同時也缺少其他級別的很多好處,因此一般都不推薦使用。

read committed(提交讀):

乙個事務開始時只能看到已經提交的事務所做的修改。也就是說乙個事務從開始一直到提交之前所做的任何修改對其他事務都是不可見的。這個級別有時候又叫做不可重複讀。大多數的系統的預設的隔離級別都是read committed。但是這個級別不能保證在同乙個事物中多次讀取相同的記錄的結果的一致(因為可能有別的事務對這些資料做出了修改並提交了)。

repeatable read(可重複讀):

repeatable read(可重複讀)在解決了髒讀的基礎上保證同乙個事務中多次讀取相同的記錄的結果是一致的。但是在理論上還存在乙個「幻讀」(phanpom)的問題。也就是在讀取某部分的記錄時候有別的事務在這部分記錄的範圍內插入了新的紀錄,那麼重複讀的時候就會出現乙個新的紀錄。不過innodb和xtradb的儲存引擎通過多版本控制(mvcc, mutivertion concurrency control)解決了「幻讀」的問題。mysql中預設使用的就是repeatable read級別。

serializable(可序列化):

強制事務序列的執行。從而避免了「幻讀」問題。它會在讀取記錄的時候對每一行都加上鎖,這樣就導致了大量的鎖競爭的問題。所以一般也很少使用。

「髒讀」和「幻讀」:「髒讀」針對的是update,delete語句,或者說針對的是修改產生的資料。核心問題還是鎖的問題,因為update和delete前提都是資料行存在,所以乙個事務能否修改記錄就取決與能否獲取到該記錄的鎖。而「幻讀」針對的是insert操作,因為資料行不存在所以當乙個事務重複讀取的時候可能看到別的事務插入的記錄。

表:

*其中mysql中預設的儲存引擎innodb使用的repeatable read級別則通過mvcc解決了「幻讀」的問題。

前面說了mysql預設的事務隔離級別是repeatable read但是大多數的資料庫的預設隔離級別都是read committed,在mysql中提供兩種方式修改事務的隔離級別

在mysql,ini配置檔案中加入

[mysqld]

transaction-isolation = read-uncommitted

可選引數有:read-uncommitted, read-committed, repeatable-read, serializable

在客戶端可以用下面的語句查詢

mysql> select @@global.tx_isolation,@@tx_isolation;

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

| @@global.tx_isolation | @@tx_isolation |

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

| repeatable-read | repeatable-read |

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

1 row in set (0.00 sec)

其中@@global.tx_isolation表示全域性的事務隔離級別,而tx_isolation表示當前會話的隔離級別。

設定隔離級別:

set [session | global] transaction isolation level

例:

mysql> set session transaction isolation level read committed;

query ok, 0 rows affected (0.00 sec)

再查詢發現已經設定成功了:

mysql> select @@global.tx_isolation,@@tx_isolation;

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

| @@global.tx_isolation | @@tx_isolation |

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

| repeatable-read | read-committed |

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

1 row in set (0.00 sec)

設定全域性的事物隔離級別:

mysql> set global transaction isolation level read committed;

query ok, 0 rows affected (0.00 sec)

這個時候再查詢:

mysql> select @@global.tx_isolation,@@tx_isolation;

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

| @@global.tx_isolation | @@tx_isolation |

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

| read-committed | read-committed |

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

1 row in set (0.00 sec)

同時我在另乙個連線中查詢發現全域性事務隔離級別已經被更改:

mysql> select @@global.tx_isolation, @@tx_isolation;

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

| @@global.tx_isolation | @@tx_isolation |

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

| read-committed | repeatable-read |

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

1 row in set (0.00 sec)

細心的人可能就會發現明明全域性事務隔離級別都修改了為什麼另外乙個連線的會話級別的事務隔離級別沒有變化。

這裡需要說明的是:當使用set修改了全域性的事務隔離級別時候只對設定以後的連線的預設事務隔離級別有影響。

這個時候我再開啟乙個新的連線就會發現預設的事務隔離級別都是read committed了。

對於這四個事務隔離級別的例項測試其實很簡單,只需要分別開兩個連線,同時開啟兩個事務(不著急commit)然後根據case測試就很容易得出結果了。這裡就不乙個乙個貼出來了。

mysql隔離級別 MySQL 事務隔離級別

mysql innodb所提供的事務滿足acid的要求,事務是通過事務日誌中的redo log和undo log來實現原子性 undo log 一致性 undo log 永續性 redo log 事務通過鎖機制實現隔離性。1 事務隔離級別與實現read uncommitted 讀未提交 read c...

mysql事務隔離級別詳解 事務的隔離級別詳解

事務的隔離級別 在資料庫操作中,為了有效保證併發讀取資料的正確性,提出的事務隔離級別。問題的提出 資料庫是要被廣大客戶所共享訪問的,那麼在資料庫操作過程中很可能出現以下幾種不確定情況。更新丟失 兩個事務都同時更新一行資料,乙個事務對資料的更新把另乙個事務對資料的更新覆蓋了。這是因為系統沒有執行任何的...

MySQL事務隔離級別

sql標準定義了4類隔離級別,包括了一些具體規則,用來限定事務內外的哪些改變是可見的,哪些是不可見的。低階別的隔離級一般支援更高的 併發處理,並擁有更低的系統開銷。read uncommitted 讀取未提交內容 在該隔離級別,所有事務都可以看到其他未提交事務的執行結果。本隔離級別很少用於實際應用,...