mysql官方文檔顯示:mysql
InnoDB中每一個隔離級別的詳細描述以下: · READ UNCOMMITTED SELECT語句以非鎖定方式被執行,可是一個可能更早期版本的記錄會被用到。所以,使用這個隔離級別,好比,讀是不連貫的。着也被稱爲「髒讀」(dirty read)。另外,這個隔離級別象READ COMMITTED同樣做用。 · READ COMMITTED 一個有些象Oracle的隔離級別。全部SELECT ... FOR UPDATE和SELECT ... LOCK IN SHARE MOD語句僅鎖定索引記錄,而不鎖定記錄前的間隙,於是容許隨意緊挨着已鎖定的記錄插入新記錄。UPDATE和DELETE語句使用一個帶惟一搜索條件的惟一的索引僅鎖定找到的索引記錄,而不包括記錄前的間隙。在範圍類型UPDATE和DELETE語句,InnoDB必須對範圍覆蓋的間隙設置next-key鎖定或間隙鎖定以及其它用戶作的塊插入。這是很必要的,由於要讓MySQL複製和恢復起做用,「幽靈行」必須被阻止掉。 持續讀行爲如同在Oracle中:即便在同一事務內, 每一個持續讀設置並讀取它本身的新快照。請參閱15.2.10.4節,「持續非鎖定讀」。 · REPEATABLE READ 這是InnoDB的默認隔離級別。帶惟一搜索條件使用惟一索引的SELECT ... FOR UPDATE, SELECT ... LOCK IN SHARE MODE, UPDATE 和DELETE語句只鎖定找到的索引記錄,而不鎖定記錄前的間隙。用其它搜索條件,這些操做採用next-key鎖定,用next-key鎖定或者間隙鎖定鎖住搜索的索引範圍,而且阻止其它用戶的新插入。 在持續讀中,有一個與以前隔離級別重要的差異:在這個級別,在同一事務內全部持續讀讀取由第一次讀所肯定的同一快照。這個慣例意味着若是你在同一事務內發出數個無格式SELECT語句,這些SELECT語句對相互之間也是持續的,請參閱15.2.10.4節,「持續非鎖定讀」。 · SERIALIZABLE 這個級別相似REPEATABLE READ,可是全部無格式SELECT語句被 隱式轉換成SELECT ... LOCK IN SHARE MODE。
1.事務裏一些有問題的讀取:髒讀,不可重複讀,幻象讀
髒讀 (dirty read):事務T1更新了一行記錄的內容,可是並無提交所作的修改。事務T2讀取更新後的行,而後T1執行回滾操做,取消了剛纔所作的修改。如今T2所讀取的行就無效了。
不可重複讀取 (nonrepeatable read):事務T1讀取一行記錄,緊接着事務T2修改 了T1剛纔讀取的那一行記錄。而後T1又再次讀取這行記錄,發現與剛纔讀取的結果不一樣。這就稱爲「不可重複」讀,由於T1原來讀取的那行記錄已經發生了變化。
幻像讀取 (phantom read):事務T1讀取一條指定的WHERE子句所返回的結果集。而後事務T2新插入 一行記錄,這行記錄剛好能夠知足T1所使用的查詢條件中的WHERE 子句的條件。而後T1又使用相同的查詢再次對錶進行檢索,可是此時卻看到了事務T2剛纔插入的新行。這個新行就稱爲「幻像」,由於對T1來講這一行就像突 然出現的同樣。
2.事務的隔離級別
從級別低到高依次爲:
READ UNCOMMITTED (讀取未提交內容):幻像讀、不可重複讀和髒讀都容許。
READ COMMITTED (讀取已提交內容):容許幻像讀、不可重複讀,但不容許髒讀。
REPEATABLE READ (可重讀):容許幻像讀,但不容許不可重複讀和髒讀。InnoDB默認級別
SERIALIZABLE (可串行化):幻像讀、不可重複讀和髒讀都不容許。
可是InnoDB的可重複讀隔離級別和其餘數據庫的可重複讀是有區別的,不會形成幻象讀(phantom read)。
ORACLE數據庫支持 READ COMMITTED 和 SERIALIZABLE ,不支持 READ UNCOMMITTED 和 REPEATABLE READ 。sql
三、修改事務隔離級別的方法:
全局修改,修改mysql.ini配置文件,在最後加上數據庫
#可選參數有:READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, SERIALIZABLE.
[mysqld]
transaction-isolation = REPEATABLE-READ
這裏全局默認是REPEATABLE-READ,其實MySQL原本默認也是這個級別安全
要記住mysql有一個autocommit參數,默認是on,他的做用是每一條單獨的查詢都是一個事務,而且自動開始,自動提交(執行完之後就自動結束了,若是你要適用select for update,而不手動調用 start transaction,這個for update的行鎖機制等於沒用,由於行鎖在自動提交後就釋放了),因此事務隔離級別和鎖機制即便你不顯式調用start transaction,這種機制在單獨的一條查詢語句中也是適用的,分析鎖的運做的時候必定要注意這一點
四、鎖機制:
共享鎖:由讀表操做加上的鎖,加鎖後其餘用戶只能獲取該表或行的共享鎖,不能獲取排它鎖,也就是說只能讀不能寫
排它鎖:由寫表操做加上的鎖,加鎖後其餘用戶不能獲取該表或行的任何鎖,典型是mysql事務中網絡
五、鎖範圍session
行鎖: 對某行記錄加上鎖
表鎖: 對整個表加上鎖
這樣組合起來就有:行級共享鎖、表級共享鎖、行級排他鎖、表級排他鎖spa
六、具體示例code
InnoDB下,開啓2個session對同一表操做,時間線往下順序執行:blog
1)READ-UNCOMMITTED(讀取未提交內容)級別索引
User A User B
SET AUTOCOMMIT=0; SET AUTOCOMMIT=0;
time
| SELECT * FROM t;
| 返回空結果
| INSERT INTO t VALUES (1, 2);
|
v SELECT * FROM t;
返回 1 row in set(User B插入)
ROLLBACK;
SELECT * FROM t;
返回空結果
COMMIT;
so:能夠看出READ-UNCOMMITTED隔離級別,當兩個事務同時進行時,即便事務沒有提交,所作的修改也會對其它事務的查詢作出影響,這種級別顯然很不安全。
2)READ-COMMITTED(讀取提交內容)級別
User A User B
SET AUTOCOMMIT=0; SET AUTOCOMMIT=0;
time
| SELECT * FROM t;
| 返回空結果
| INSERT INTO t VALUES (1, 2);
|
v SELECT * FROM t;
返回空結果(未更改)
COMMIT;
SELECT * FROM t;
返回 1 row(UserB插入並提交了)
COMMIT;
so:READ-COMMITTED事務隔離級別,只有在事務提交後,纔會對另外一個事務產生影響。
3)REPEATABLE-READ(可重讀)
User A User B
SET AUTOCOMMIT=0; SET AUTOCOMMIT=0;
time
| SELECT * FROM t;
| 返回空結果
| INSERT INTO t VALUES (1, 2);
|
v SELECT * FROM t;
返回空結果(未更改)
COMMIT;
SELECT * FROM t;
返回空結果(仍未更改)
COMMIT;
SELECT * FROM t;
返回1 row(新啓事務,查詢到修改)
so:REPEATABLE-READ(可重讀)事務隔離級別,當兩個事務同時進行時,其中一個事務修改數據對另外一個事務不會形成影響,即便修改的事務已經提交也不會對另外一個事務形成影響,直到使用新的事務。
4)SERIERLIZED(可串行化)
爲方便解釋,假設表中已有一條數據
User A User B
SET AUTOCOMMIT=0;
SET AUTOCOMMIT=0;
time
| SELECT * FROM t;
| 返回1 row
| SELECT * FROM t;
| 返回1 row
v
UPDATE此行;
被加鎖,等待
so:SERIERLIZED(可串行化)事務隔離級別最高,在進行查詢時就會對錶或行加上共享鎖,其餘事務對該表將只能進行讀操做,而不能進行寫操做。
(以上內容含網絡摘錄,若有侵犯,多多包涵)