1. 程式人生 > >鎖和隔離級別--mysql sql 20170526更新

鎖和隔離級別--mysql sql 20170526更新

刪掉了之前的部落格(摘抄,不精準,理解欠佳)

資料庫隔離級別:

資料庫事務的隔離級別有4個,由低到高依次為Read uncommittedRead committedRepeatable readSerializable,這四個級別可以逐個解決髒讀、不可重複讀、幻讀這幾類問題。

隔離級別

髒讀

非重複讀

幻像讀

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鎖,則其它事務只能再對AS鎖,而不能加X鎖,直到T釋放A上的S鎖。這就保證了其它事務可以讀A,但在T釋放A上的S鎖之前不能對A做任何修改。

封鎖協議

排它鎖

共享鎖

一致性保證

操作結束釋放

事務結束釋放

操作結束釋放

事務結束釋放

不丟失修改

不髒讀

可重複讀

一級

二級

三級

Mysql資料第三級鎖協議,但是從上面的例子可以看到它並不是嚴格的第三級鎖協議。

在查詢時它運用了資料的快照。

Mysql不同引擎的鎖型別,行級鎖、頁鎖、表鎖

面試問道:測試使用int型別索引:

= 1 >1 <> 1 、各種like 1 % is nullBETWEEN  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';