1.概念:給單獨的一行記錄加鎖,主要應用於innodb表存儲引擎mysql
2.特色:在innodb存儲引擎中應用比較多,支持事務、開銷大、加鎖慢;會出現死鎖;鎖的粒度小,併發狀況下,產生鎖等待的機率比較低,因此支持的併發數比較高。sql
1.概念:事務是一系列操做組成的工做單元,該工做單元內的操做是不可分割的,也就是說要麼所有都執行,要麼所有不執行。數據庫
2.特性:ACIDbash
1.問題session
注:不可重複讀的重點是修改,一樣的條件,你讀取過的數據,再次讀取出來發現值不同。併發
幻讀的重點在於新增或者刪除,一樣的條件,第 1 次和第 2 次讀出來的記錄數不同。spa
2.解決方案--數據庫隔離機制code
解決了丟失更新,可是會出現髒讀、不可重複讀、幻讀。cdn
解決了丟失更新和髒讀,可是會出現不可重複讀和幻讀。blog
解決了丟失更新、髒讀和不可重複讀,可是會出現幻讀。
解決了全部的問題。
注:樂觀所能夠解決幻讀。
查看mysql事務隔離級別:show variables like 'tx_iso%';
前提:set autocommit=0; // 設置自動提交事務爲手動提交
/* 行鎖案例*/
create table lock_two(
id int,
col int
)engine=innodb;
insert into lock_two(id,col) values (1,1);
insert into lock_two(id,col) values (2,2);
insert into lock_two(id,col) values (3,3);
複製代碼
1.在session1中執行update : update lock_two set col=11 where id=1;
(1)分別在session1和session2中查詢lock_two,看id爲1的記錄的col是否修改了。
發現session1 的記錄修改了,session2中的記錄沒有被修改。
(2)在session1中執行commite後,而後再在session2中查詢:
發現session2中的表數據改變了。
2.在session1中執行update:update lock_two set col=11 where id=1,不執行commit;
在session2中執行uodate :update lock_two set col=11 where id=1,不執行commit;
發現session2中的update發生阻塞,而且超過一段時間報錯。
3.在session1中執行update:update lock_two set col=22 where id = 2; 不執行commit
在session2中執行另外一條update:update lock_two set col=33 where id = 3;
此時,session2中的update發生阻塞,在沒發生錯誤的狀況下,session1執行commit,session2中的update會立刻執行。4.在lock_two中建立索引,
create index idx_id on lock_two(id);
create index idx_col on lock_two(col);
複製代碼
而後重複第3步,
發現session2能夠更新,不會產生阻塞。由於用上了索引,至關於行鎖。
結論:若是沒有用上索引,行鎖變成表鎖
begin;
select * from lock_two where id=2 for update;
複製代碼
1.定義
在範圍查找的狀況下, innodb會給範圍條件中的數據加上鎖,不管數據是不是否真實存在。
2.例子
在session1中update:update lock_two set col=666 where id>2 and id<8;
1) 在session2中執行insert:insert into lock_two values(9,99);
插入執行成功!
2) 在session2中執行insert:insert into lock_two values(7,77);
插入阻塞,一段時間後報錯!
執行select:select * from lock_two where id=4;
查詢成功!
建議:在innodb中,由於有間隙鎖的存在,最好在where中少使用這種範圍查找。
show status like 'innodb_row_lock%';
說明: