鎖和隔離級別--mysql sql 20170526更新
刪掉了之前的部落格(摘抄,不精準,理解欠佳)
資料庫隔離級別:
資料庫事務的隔離級別有4個,由低到高依次為Read uncommitted、Read committed、Repeatable read、Serializable,這四個級別可以逐個解決髒讀、不可重複讀、幻讀這幾類問題。
隔離級別 |
髒讀 |
非重複讀 |
幻像讀 |
read uncommitted |
允許 |
允許 |
允許 |
read committed |
允許 |
允許 |
|
repeatable read |
允許 |
||
serializable |
Oracle手動提交,預設read committed
Mysql是自動提交,預設Repeatable read。
Read uncommitted 可以讀到別的事務未提交的資料/事務回滾造成髒讀
Read committed 在一個事務中可以讀到其他事務提交的資料,這樣在提交前後讀到的資料不一致 無法重複讀。
Repeatable read 在開啟一個事務修改資料未提交時,其他事務無法對該資料做修改操作,避免了無法重複讀的問題。
Serializable:指的是其他隔離級別無法保證有無新增資料。兩次查詢結果可能多了N條資料記錄。
【開啟事務做查詢時,在其他事務提交前後查詢出來資料一致,參考MVCC ,此事務在讀取時讀取的是mysql快照資訊】
關於此 Repeatable read實踐
參考http://blog.csdn.net/dong976209075/article/details/8802778
Mvcc參考http://blog.csdn.net/chen77716/article/details/6742128#comments
資料庫鎖和封鎖協議:
悲觀所和樂觀所:
是否加鎖:
悲觀鎖(Pessimistic Lock), 顧名思義,就是很悲觀,每次去拿資料的時候都認為別人會修改,所以每次在拿資料的時候都會上鎖,這樣別人想拿這個資料就會block直到它拿到鎖。傳統的關係型資料庫裡邊就用到了很多這種鎖機制,比如行鎖,表鎖等,讀鎖,寫鎖等,都是在做操作之前先上鎖。
樂觀鎖(Optimistic Lock), 顧名思義,就是很樂觀,每次去拿資料的時候都認為別人不會修改,所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個資料,可以使用版本號等機制。樂觀鎖適用於多讀的應用型別,這樣可以提高吞吐量,像資料庫如果提供類似於write_condition機制的其實都是提供的樂觀鎖。
排它鎖和共享鎖:
1 封鎖型別(Locking)
封鎖是實現併發控制的一個非常重要的技術。所謂封鎖就是事務T在對某個資料物件例如表、記錄等操作之前,先向系統發出請求,對其加鎖。加鎖後事務T就對該資料物件有了一定的控制,在事務T釋放它的鎖之前,其它的事務不能更新此資料物件。基本的封鎖型別有兩種:排它鎖(Exclusive
locks簡記為X鎖)和共享鎖(Share locks簡記為S鎖)。
排它鎖又稱為寫鎖。若事務T對資料物件A加上X鎖,則只允許T讀取和修改A,其它任何事務都不能再對A加任何型別的鎖,直到T釋放A上的鎖。這就保證了其它事務在T釋放A上的鎖之前不能再讀取和修改A。
共享鎖又稱為讀鎖。若事務T對資料物件A加上S鎖,則其它事務只能再對A加S鎖,而不能加X鎖,直到T釋放A上的S鎖。這就保證了其它事務可以讀A,但在T釋放A上的S鎖之前不能對A做任何修改。
封鎖協議 |
排它鎖 |
共享鎖 |
一致性保證 |
||||
操作結束釋放 |
事務結束釋放 |
操作結束釋放 |
事務結束釋放 |
不丟失修改 |
不髒讀 |
可重複讀 |
|
一級 |
√ |
√ |
|||||
二級 |
√ |
√ |
√ |
√ |
|||
三級 |
√ |
√ |
√ |
√ |
√ |
Mysql資料第三級鎖協議,但是從上面的例子可以看到它並不是嚴格的第三級鎖協議。
在查詢時它運用了資料的快照。
Mysql不同引擎的鎖型別,行級鎖、頁鎖、表鎖
面試問道:測試使用int型別索引:
= 1 、>1 、 <> 1 、各種like 1 加% 、is null、BETWEEN and、都會用到索引
面試查詢第二大:
select max(id) from table where id<(select max(id) from table);
衍生查詢第N大:
select max(id) from table where id not in (select t.id from (select id from table ORDER BY id desc limit 3) t)
研究第N大 question:
This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
這版本的 MySQL 不支援使用LIMIT子句的IN/ALL/ANY/SOME子查詢,即是支援非IN/ALL/ANY/SOME子查詢的LIMIT子查詢。
也就是說,這樣的語句是不能正確執行的。
select * from table where id in (select id from table limit 10)
20170710:
SELECT * FROM `test` LIMIT n,m; 查詢從n+1的m個數據
SELECT * FROM `test` LIMIT n OFFSET m ;查詢從M+1開始的N條資料
主外來鍵關聯清空資料、刪表等操作。
set FOREIGN_key_checks = 0;
set FOREIGN_key_checks = 1;
// 寫mysql資料庫文件用,用此sql查詢關鍵資訊,再貼到word檔案表格中,done!
SELECT
column_name,
COLUMN_TYPE,
IS_NULLABLE,
COLUMN_COMMENT,
COLUMN_DEFAULT,
COLUMN_KEY
FROM
information_schema. COLUMNS
WHERE
table_name = 'table'
AND table_schema = 'db';