我們知道,在關聯式資料庫標準中有四個交易隔離等級:
未提交讀(Read Uncommitted):允許髒讀,也就是可能讀取到其他會話中未提交事務修改的資料
提交讀(Read Committed):只能讀取到已經提交的資料。Oracle等多數資料庫預設都是該層級
可重複讀(Repeated Read):可重複讀。在同一個事務內的查詢都是事務開始時刻一致的,InnoDB預設層級。在SQL標準中,該隔離等級消除了不可重複讀取,但是還存在幻象讀
串列讀(Serializable):完全序列化的讀,每次讀都需要獲得表級共用鎖定,讀寫相互都會阻塞
查看InnoDB系統層級的交易隔離等級:
以下為引用的內容:
mysql> SELECT @@global.tx_isolation;
+-----------------------+
| @@global.tx_isolation |
+-----------------------+
| REPEATABLE-READ |
+-----------------------+
1 row in set (0.00 sec)
查看InnoDB會話層級的交易隔離等級:
以下為引用的內容:
mysql> SELECT @@tx_isolation;
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set (0.00 sec)
修改交易隔離等級:
以下為引用的內容:
mysql> set global transaction isolation level read committed;
Query OK, 0 rows affected (0.00 sec)
mysql> set session transaction isolation level read committed;
Query OK, 0 rows affected (0.00 sec)
InnoDB的可重複讀隔離等級和其他資料庫的可重複讀是有區別的,不會造成幻象讀(phantom read),所謂幻象讀,就是同一個事務內,多次select,可以讀取到其他session insert並已經commit的資料。下面是一個小的測試,證明InnoDB的可重複讀隔離等級不會造成幻象讀。測試涉及兩個session,分別為session 1和session 2,隔離等級都是repeateable read,關閉autocommit
以下為引用的內容:
mysql> select @@tx_isolation;
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set (0.00 sec)
mysql> set autocommit=off;
Query OK, 0 rows affected (0.00 sec)
session 1 建立表並插入測試資料
mysql> create table test(i int) engine=innodb;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into test values(1);
Query OK, 1 row affected (0.00 sec)
session 2 查詢,沒有資料,正常,session1沒有提交,不允許髒讀
mysql> select * from test;
Empty set (0.00 sec)
session 1 提交事務
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
session 2 查詢,還是沒有資料,沒有產生幻象讀
mysql> select * from test;
Empty set (0.00 sec)
以上實驗版本:
mysql> select version();
+-------------------------+
| version() |
+-------------------------+
| 5.0.37-community-nt-log |
+-------------------------+
1 row in set (0.00 sec)