萬盛學電腦網

 萬盛學電腦網 >> 數據庫 >> mysql教程 >> mysql中不同事務隔離級別下數據的顯示效果

mysql中不同事務隔離級別下數據的顯示效果

   事務是一組原子性的SQL查詢語句,也可以被看做一個工作單元。如果數據庫引擎能夠成功地對數據庫應用所有的查詢語句,它就會執行所有查詢,如果任何一條查詢語句因為崩潰或其他原因而無法執行,那麼所有的語句就都不會執行。也就是說,事務內的語句要麼全部執行,要麼一句也不執行。

  事務的特性:acid,也稱為事務的四個測試(原子性,一致性,隔離性,持久性)

  automicity:原子性,事務所引起的數據庫操作,要麼都完成,要麼都不執行

  consisitency:一致性,事務執行前的總和和事務執行後的總和是不變的

  isolation:隔離性, 某個事務的結果只有在完成之後才對其他事務可見

  durability:持久性,一旦事務成功完成,系統必須保證任何故障都不會引起事務表現出不一致性

  事務的狀態:

  活動

  部分提交

  失敗

  中止

  提交

  事務在某一時刻,一定處於上邊五種狀態中的一種,事務各狀態之間的轉換如下所示:

mysql中不同事務隔離級別下數據的顯示效果 三聯

  事務並發導致的問題

  髒讀(Drity Read):某個事務已更新一份數據,另一個事務在此時讀取了同一份數據,由於某些原因,前一個RollBack了操作,則後一個事務所讀取的數據就會是不正確的。

  不可重復讀(Non-repeatable read):在一個事務的兩次查詢之中數據不一致,這可能是兩次查詢過程中間插入了一個事務更新了原有的數據。

  幻讀(Phantom Read):在一個事務的兩次查詢中數據不一致,例如有一個事務查詢了幾列(Row)數據,而另一個事務卻在此時插入了新的幾列數據,先前的事務在接下來的查詢中,就會發現有幾列數據是它先前所沒有的。

  並發控制

  多版本並發控制: Multiversion concurrency control,MVCC

  每個用戶操作數據時都是源數據的時間快照,當用戶操作完成後,依據各快照的時間點在合並到源數據中

  鎖:要想實現並發控制,最簡單的實現機制就是鎖(MVCC采用的不是鎖機制)。

  讀鎖:共享鎖,由讀表操作加上的鎖,加鎖後其他用戶只能獲取該表或行的共享鎖,不能獲取排它鎖,也就是說只能讀不能寫

  寫鎖:獨占鎖,由寫表操作加上的鎖,加鎖後其他用戶不能獲取該表或行的任何鎖

  鎖粒度:從大到小,MySQL服務器僅支持表級鎖,行鎖需要存儲引擎完成。

  表鎖:鎖定某個表

  頁鎖:鎖定某個頁

  行鎖:鎖定某行

  粒度越精細,並發性越好。即行鎖的並發性最好,但需要存儲引擎的支持。

  事務的四種隔離級別

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

  讀提交(read committed): 只能讀取到已經提交的數據。oracle等多數數據庫默認都是該級別

  可重讀(repeatable read): 在同一個事務內的查詢都是事務開始時刻一致的,innodb的默認級別。在SQL標准中,該隔離級別消除了不可重復讀,但是還存在幻象讀

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

  在MySQL中,在並發控制情況下,不同隔離級別分別有可能產生問題如下所示:

  上邊之所以介紹那麼多理論知識,是為了便於理解。在上邊的表格中已經列出來了,在不同隔離級別下,數據的顯示效果可能出現的問題,現在在linux上安裝好mysql,通過我們的實驗來一起看一下在不同隔離級別下數據的顯示效果吧。

  實驗環境:

  linux系統:RedHat 5.8

  linux內核:linux-2.6.18-308.el5

  mysql版本:mysql-5.6.10-linux-glibc2.5-i686

  本次實驗的所有操作均在虛擬機中完成,通過Xmanager連接虛擬機,然後打開兩個會話連接,在兩個會話中,同時更改隔離級別,然後查看數據的顯示效果。

  本次實驗中mysql采用源碼編譯安裝的方式安裝mysql,你也可以使用rpm包的方式直接安裝mysql。具體源碼安裝的方式及過程,這裡不再演示,在前面的博客中,我已經介紹了很多次。如果你采用源碼編譯安裝的方式,不知道如何安裝mysql,可參看我以前寫的博客,裡邊都有介紹。采用源碼編譯安裝的方式,在mysql的配置文件中,最好啟用每表一個表空間。這裡我們直接啟用。

  因為是實驗,這裡沒有對mysql設置密碼,因此,我們直接使用命令進入mysql。命令及顯示效果如下:

  50[root@mysql ~]# mysql -uroot -p #使用該命令進入mysql,因為沒有設置密碼,在要求輸入密碼時直接按回車鍵即可

  Enter password:

  Welcome to the MySQL monitor. Commands end with ; or g.

  Your MySQL connection id is 2

  Server version: 5.6.10 MySQL Community Server (GPL)

  Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.

  Oracle is a registered trademark of Oracle Corporation and/or its

  affiliates. Other names may be trademarks of their respective

  owners.

  Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.

  mysql> show variables like '%iso%'; #查看mysql默認的事務隔離級別,默認為可重讀。也可以使用select @@tx_isolation命令查看

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

  | Variable_name | Value |

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

  | tx_isolation | REPEATABLE-READ |

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

  1 row in set (0.36 sec)

  mysql> show databases; #查看系統已經存在的數據庫

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

  | Database |

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

  | information_schema |

  | mysql |

  | performance_schema |

  | test |

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

  4 rows in set (0.00 sec)

  現在導入我們實驗所使用的數據庫。

  [root@mysql ~]# mysql < jiaowu.sql #導入實驗所用的jiaowu數據庫

  [root@mysql ~]# mysql -uroot -p

  Enter password:

  Welcome to the MySQL monitor. Commands end with ; or g.

  Your MySQL connection id is 7

  Server version: 5.6.10 MySQL Community Server (GPL)

  Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.

  Oracle is a registered trademark of Oracle Corporation and/or its

  affiliates. Other names may be trademarks of their respective

  owners.

  Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.

  mysql> show databases; #查看導入的jiaowu數據庫是否存在

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

  | Database |

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

  | information_schema |

  | jiaowu |

  | mysql |

  | performance_schema |

  | test |

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

  5 rows in set (0.01 sec)

  我們在mysql命令界面下,沒有明確啟用事務時,輸入的每個命令都是直接提交的,因為mysql中有個變量的值,可實現自動提交。也就是說我們每輸入一個語句,都會自動提交,這會產生大量的磁盤IO,降低系統的性能。在我們做實驗時,因為我們要明確使用事務,所以,建議關閉自動提交的功能,如果不關閉也沒有關系,但是如果你沒有明確使用事務,想要做下邊的實驗,那就需要關閉此功能了。這裡,我們明確使用事務,且關閉自動提交功能。假如你關閉了自動提交功能,需明確使用事務,否則你輸入的所有語句會被當成一個事務進行處理。命令如下:

  16mysql> select @@autocommit; #查看該值,為1表示啟動自動提交

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

  | @@autocommit |

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

  | 1 |

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

  1 row in set (0.00 sec)

  mysql> set autocommit=0; #關閉自動提交功能

  Query OK, 0 rows affected (0.00 sec)

  mysql> select @@autocommit; #重新查看該值,為0表示關閉自動提交功能

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

  | @@autocommit |

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

  | 0 |

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

  1 row in set (0.00 sec)

  現在打開兩個會話,在這兩個會話中分別進入mysql,首先記得要就修改兩個回話中的autocommit變量,關閉自動提交功能,然後查看事務的隔離級別,默認為REPEATABLE-READ。在兩個會話中都需要修改隔離級別。我們先從最低的隔離級別開始演示。

  30mysql> select @@tx_isolation;

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

  | @@tx_

copyright © 萬盛學電腦網 all rights reserved