mysql隔離級別和鎖的講解

2021-12-30 10:13:50 字數 2343 閱讀 5325

在資料庫操作中,為了有效保證併發讀取資料的正確性,提出的事務隔離級別。資料庫鎖,實現這些隔離級別存在的。未提交讀(read uncommitted):

允許髒讀,也就是可能讀取到其他會話中未提交事務修改的資料提交讀(read committed):

只能讀取到已經提交的資料。oracle等多數資料庫預設都是該級別 (不重複讀).

解決髒讀問題.會發生不可重複讀現象.可重複讀(repeated read):

在同乙個事務內的查詢都是事務開始時刻一致的,innodb預設級別。

解決不可重複讀,但是還存在幻象讀(innodb解決了)序列讀(serializable):

完全序列化的讀,每次讀都需要獲得表級共享鎖,讀寫相互都會阻塞設定隔離級別

set session transaction isolatin level repeatable read;

set global transaction isolation level repeatable read;檢視隔離級別

select @@tx_isolation;

select @@global.tx_isolation;不可重複讀

不可重複讀是原先查詢出來的資料發生更改.重點在於update和delete,

解決方法是在可重複讀中,該sql第一次讀取到資料後,就將這些資料加鎖,其它事務無法修改這些資料,就可以實現可重複讀了。幻讀

幻讀的重點在於insert。

當事務a先前讀取了資料,或者修改了全部資料,事務b還是可以insert資料提交,這時事務a就會發現莫名其妙多了一條之前沒有的資料,這就是幻讀,不能通過行鎖來避免。需要serializable隔離級別 ,讀用讀鎖,寫用寫鎖,讀鎖和寫鎖互斥.表鎖是對一整張表加鎖,雖然可分為讀鎖和寫鎖,但畢竟是鎖住整張表,會導致併發能力下降,一般是做ddl處理時使用。

行鎖則是鎖住資料行,這種加鎖方法比較複雜,但是由於只鎖住有限的資料,對於其它資料不加限制,所以併發能力強,mysql一般都是用行鎖來處理併發事務。悲觀鎖

在悲觀鎖的情況下,為了保證事務的隔離性,就需要一致性鎖定讀。讀取資料時給加鎖,其它事務無法修改這些資料。修改刪除資料時也要加鎖,其它事務無法讀取這些資料。

悲觀鎖大多數情況下依靠資料庫的鎖機制實現,以保證操作最大程度的獨占性。但隨之而來的就是資料庫效能的大量開銷,特別是對長事務而言,這樣的開銷往往無法承受。樂觀鎖

樂觀鎖機制在一定程度上解決了這個問題。樂觀鎖,大多是基於資料版本( version )記錄機制實現。

何謂資料版本?即為資料增加乙個版本標識,在基於資料庫表的版本解決方案中,一般是通過為資料庫表增加乙個 「version」 欄位來實現。讀取出資料時,將此版本號一同讀出,之後更新時,對此版本號加一。此時,將提交資料的版本資料與資料庫表對應記錄的當前版本資訊進行比對,如果提交的資料版本號大於資料庫表當前版本號,則予以更新,否則認為是過期資料。要說明的是,mvcc的實現沒有固定的規範,每個資料庫都會有不同的實現方式,這裡討論的是innodb的mvcc。

在innodb中,會在每行資料後新增兩個額外的隱藏的值來實現mvcc,這兩個值乙個記錄這行資料何時被建立,另外乙個記錄這行資料何時過期(或者被刪除)。 在實際操作中,儲存的並不是時間,而是事務的版本號,每開啟乙個新事務,事務的版本號就會遞增。 在可重讀repeatable reads事務隔離級別下:

select時,讀取建立版本號<=當前事務版本號,刪除版本號為空當前事務版本號。

insert時,儲存當前事務版本號為行的建立版本號

delete時,儲存當前事務版本號為行的刪除版本號

update時,插入一條新紀錄,儲存當前事務版本號為行建立版本號,同時儲存當前事務版本號到原來刪除的行

通過mvcc,雖然每行記錄都需要額外的儲存空間,更多的行檢查工作以及一些額外的維護工作,但可以減少鎖的使用,大多數讀操作都不用加鎖,讀資料操作很簡單,效能很好,並且也能保證只會讀取到符合標準的行,也只鎖住必要行。我們不管從資料庫方面的教課書中學到,還是從網路上看到,大都是上文中事務的四種隔離級別這一模組列出的意思,rr級別是可重複讀的,但無法解決幻讀,而只有在serializable級別才能解決幻讀。於是我就加了乙個事務c來展示效果。在事務c中新增了一條teacher_id=1的資料commit,rr級別中應該會有幻讀現象,事務a在查詢teacher_id=1的資料時會讀到事務c新加的資料。但是測試後發現,在mysql中是不存在這種情況的,在事務c提交後,事務a還是不會讀到這條資料。可見在mysql的rr級別中,是解決了幻讀的讀問題的。

為了解決當前讀中的幻讀問題,mysql事務使用了next-key鎖。

next-key鎖

next-key鎖是行鎖和gap(間隙鎖)的合併,行鎖上文已經介紹了,接下來說下gap間隙鎖。

行鎖防止別的事務修改或刪除,gap鎖防止別的事務新增,行鎖和gap鎖結合形成的的next-key鎖共同解決了rr級別在寫資料時的幻讀問題。

Mysql 鎖 隔離級別

1.共享鎖 只要有乙個人 事務或執行緒 在查詢,其他人就都不能改,要照顧少數 下面是將所有性別是男的資料都加上共享鎖 select from table where 男 lock in share mode2.排他鎖 只要有乙個人 事務或執行緒 在用 增刪改差 其他人就不能用 下面是將所有性別是男的...

mysql 鎖,隔離級別

1.鎖是對多執行緒,多程序訪問同一資源進行協調的機制 2.分為行鎖,表鎖,頁鎖。myisam和memory支援表鎖,bdb引擎支援表鎖,頁鎖。innodb支援表鎖,行鎖 預設 3.myisam表鎖 4.myisam併發插入 5.讀寫操作同時爭搶鎖,寫鎖優先,可以設定寫鎖優先順序降低,low prio...

MySQL的事務隔離級別和鎖

mysql的事務隔離級別 read uncommitted 讀未提交資料 read committed 讀已提交資料 repeatable read 可重讀 serializable 可序列化 檢視mysql的事務隔離級別 預設 全域性和會話事務隔離級別 select tx isolation se...