欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

深入理解Mysql事務隔離級別與鎖機制問題

 更新時間:2021年09月28日 10:47:15   作者:daidavid_csdn  
MySQL默認的事務隔離級別是可重復讀,用Spring開發(fā)程序時,如果不設置隔離級別默認用MySQL設置的隔離級別,如果Spring設置了就用已設置的隔離級別,本文重點給大家介紹Mysql事務隔離級別與鎖機制的相關知識,一起看看吧

概述

數(shù)據庫一般都會并發(fā)執(zhí)行多個事務,多個事務可能會并發(fā)的對相同的一批數(shù)據進行增刪改查操作,可能導致臟讀、臟寫、不可重復度和幻讀。這些問題的本質都是數(shù)據庫的多事務并發(fā)問題,為了解決事務并發(fā)問題,數(shù)據庫設計了事務隔離機制、鎖機制、MVCC多版本并發(fā)控制隔離機制,用一整套機制來解決多事務并發(fā)問題。

事務及其ACID屬性

原子性:操作的不可分割;

一致性:數(shù)據的一致性;

隔離性:事務之間互不干擾;

持久性:數(shù)據的修改時永久的;

并發(fā)事務處理帶來的問題

臟寫:丟失更新,最后的更新覆蓋了由其他事務所做的更新;

臟讀:事務A讀取到了事務B已經修改但未提交的數(shù)據;

不可重復讀:事務內部相同的查詢在不同時刻結果不一樣,針對的是數(shù)據的更新、刪除操作;

幻讀:事務A讀取到了其后開始的事務B提交的新增數(shù)據;針對的是數(shù)據的插入;

事務隔離級別

隔離級別 臟讀 不可重復讀 幻讀
讀未提交
讀已提交 ×
可重復讀 × ×
可串行化 × × ×

 READ-UNCONMMITTED、READ-COMMITTED、REPEATABLE-READ、SERIALIZABLE

查看當前數(shù)據庫的事務隔離級別:

show variables like 'tx_isolation'

設置事務隔離級別:

set tx_isolation='REPEATABLE-READ';

MySQL默認的事務隔離級別是可重復讀,用Spring開發(fā)程序時,如果不設置隔離級別默認用MySQL設置的隔離級別,如果Spring設置了就用已設置的隔離級別;

鎖詳解

鎖是計算機協(xié)調多個進程或線程并發(fā)訪問某一資源的機制。

鎖分類

從性能上分為:樂觀鎖(用版本對比來實現(xiàn))和悲觀鎖;

從對數(shù)據庫操作類型分:讀寫和寫鎖(悲觀鎖);

        讀鎖(共享鎖,S鎖(Shared)):針對同一份數(shù)據,多個讀操作可以同時進行而不會互相影響;

        寫鎖(排它鎖,X鎖(exclusive)):當前寫操作沒有完成前,阻斷其他寫鎖和讀鎖;

從對數(shù)據庫操作的粒度分:表鎖和行鎖

        表鎖:每次操作鎖住整張表,開銷小,加鎖快;不會出現(xiàn)死鎖;鎖定粒度大,發(fā)生鎖沖突的概率最高,并發(fā)度最低;一般用在整表數(shù)據遷移的場景。

# 手動增加表鎖
lock table 表名稱 read(write),表名稱2 read(write);
# 查看表上加過的鎖
show open tables;
# 刪除表鎖
unlock tables;

        行鎖:每次操作鎖住一行數(shù)據。開銷大,加鎖慢;會出現(xiàn)死鎖;鎖定粒度最小,發(fā)生鎖沖突的概率最低,并發(fā)度最高。

InnoDB與MYISAM的最大不同點:1、InnoDB支持事務;2、InnoDB支持行級鎖。

總結:

MyISAM在執(zhí)行查詢語句前,會自動給涉及的表加讀鎖;執(zhí)行update、insert、delete操作加寫鎖;

InnoDB在執(zhí)行查詢語句前(非串行隔離級別),不會加鎖;執(zhí)行update、insert、delete操作會加行鎖。

讀鎖會阻塞寫,但不會阻塞讀。而寫鎖會把讀寫都阻塞。

行鎖與事務隔離級別案例分析

 mysql準備一張表

1、臟讀,事務A讀取到另外一個事務已修改但未提交的數(shù)據,此種情形簡單,不具體闡述。對應的事務隔離級別:read uncommitted(讀未提交)。

2、不可重復讀,對應的事務隔離級別:read committed(讀已提交)

事務A:

set session transaction isolation level read committed;
 
start transaction;
 
select * from t_user;

事務B:

set session transaction isolation level read committed;
 
start transaction;
 
-- insert into t_user values (1,'張',8);
update t_user set age = 9 where id = 1;
 
commit;

事務A第一次執(zhí)行到查詢語句,結果如下:

此時,事務B執(zhí)行完畢,事務A還未結束,繼續(xù)執(zhí)行一次查詢,結果如下:

 

 產生了不可重復讀的問題,一個事務內前后兩次查詢的數(shù)據結果不一致,讀取到了其他事務已經提交的數(shù)據。

3、可重復讀,設置事務隔離級別為repeatable read(可重復讀);

事務A第一次執(zhí)行結果如下:

 事務B執(zhí)行,修改操作,update  age=8并提交,結果對比如下

 左邊為事務A,查詢結果與開始時一樣,解決了不可重復讀的問題;直接查詢,此時age=8;

可重復讀的隔離級別下使用了MVCC(multi-version concurrency control)機制,select操作不會更新版本號,是快照讀(歷史版本);insert、update和delete會更新版本號,是當前讀(當前版本)。

4、幻讀,在3中,新增一條數(shù)據,如下

 此時事務A再次查詢,結果如下:

 結果依然和開始的一樣,此種場景,可重復讀隔離級別有效的防止了不可重復讀和幻讀的問題;

如果,事務A,在第一次查詢后,執(zhí)行不加條件的update,這個update會作用在所有的行上面,包括事務B新增加的數(shù)據。此時,再執(zhí)行查詢,結果如下:

 出現(xiàn)了幻讀,Mysql官方給出的幻讀解釋是:只要在一個事務中,第二次select多出了row計算幻讀。

5、串行化,serializable,InnoDB的查詢也會被加上行鎖。如果查詢的是一個范圍,那么該范圍內的所有記錄行包括每行記錄所在的間隙區(qū)間范圍都會被加鎖,即使該行數(shù)據還沒有被插入。

間隙鎖(Gap Lock)

session_1執(zhí)行update t_user set name ='哈哈' where id>8 and id<18;則其他session無法在這個范圍包含的所有行記錄以及行記錄所在的間隙里插入或修改任何數(shù)據

間隙鎖在可重復讀隔離級別下才會生效

臨鍵鎖(Next-key Locks)

Next-key Locks是行鎖與間隙鎖的組合。在間隙鎖(8,18)這個范圍,實際會找到存在的值,比如id距離這個區(qū)間最近的是,3,20;則實際在(3,20]這個范圍都處在行鎖范圍內。

無索引行鎖會升級為表鎖

鎖主要是加在索引上,如果對非索引字段更新,行鎖可能會變表鎖。

InnoDB的行鎖是針對索引加的鎖,不是針對記錄加的鎖。并且該索引不能失效,否則都會從行鎖升級為表鎖

鎖定某一行還可以用lock in share mode(共享鎖)和for update(排它鎖)

結論:

Innodb存儲引擎由于實現(xiàn)了行級鎖定,雖然在鎖定機制的實現(xiàn)方面所帶來的性能損耗可能比表級鎖定會更高,但是在整體并發(fā)處理能力方面要遠遠優(yōu)于MYISAM的表級鎖定。

但是,Innodb的行級鎖定同樣有其脆弱的一面,如使用不當,可能會讓整體的性能更差。

行鎖分析

通過檢查InnoDB_row_lock狀態(tài)變量來分析系統(tǒng)上的行鎖的爭奪情況

show status like 'innodb_row_lock%';

比較重要的主要有:

Innodb_row_lock_time_avg(等待平均時長)

Innodb_row_lock_waits(等待總次數(shù))

Innodb_row_lock_time(等待總時長)

當?shù)却螖?shù)很高,且每次等待時長也不小的時候,就需要分析系統(tǒng)中為什么會有如此多的等待,根據分析結果制定優(yōu)化計劃。

死鎖

set session transaction isolation level repeatable read;
 
start transaction;
 
select * from t_user where id = 2 for update;
select * from t_user where id = 1 for update;

事務A先鎖定id=1,再鎖定id=2;事務B順序相反,出現(xiàn)死鎖,結果如下:

 大多數(shù)情況Mysql可以自動檢測死鎖并回滾產生死鎖的那個事務,但有些情況無招。

查看近期死鎖日志信息:

show engine innodb status\G;

鎖優(yōu)化建議:

1、盡可能讓所有數(shù)據檢索都通過索引來完成,避免無索引行鎖升級為表鎖;

2、合理設計索引,盡量縮小鎖的范圍;

3、盡可能減少索引條件范圍,避免間隙鎖;

4、盡量控制事務大小,減少鎖定資源量和時間長度,涉及事務加鎖的sql盡量放在事務最后執(zhí)行;

5、盡可能低級別事務隔離

到此這篇關于深入理解Mysql事務隔離級別與鎖機制的文章就介紹到這了,更多相關Mysql事務隔離級別與鎖機制內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • mysql格式化小數(shù)保留小數(shù)點后兩位(小數(shù)點格式化)

    mysql格式化小數(shù)保留小數(shù)點后兩位(小數(shù)點格式化)

    今天遇到一個問題,格式化浮點數(shù)的問題,用format(col,2)保留兩位小數(shù)點,出現(xiàn)一個問題,例如下面的語句,后面我們給出解決方法
    2013-12-12
  • MySQL 修改數(shù)據庫名稱的一個新奇方法

    MySQL 修改數(shù)據庫名稱的一個新奇方法

    這篇文章主要介紹了MySQL 修改數(shù)據庫名稱的一個新奇方法,MySQL 修改數(shù)據庫名的一個變通方法,需要的朋友可以參考下
    2014-07-07
  • mysql視圖原理與用法實例小結

    mysql視圖原理與用法實例小結

    這篇文章主要介紹了mysql視圖原理與用法,結合實例形式分析了mysql視圖的概念、原理、創(chuàng)建、使用方法及相關注意事項,需要的朋友可以參考下
    2018-04-04
  • MySQL的源碼安裝及使用UDFs進行數(shù)據自動更新的教程

    MySQL的源碼安裝及使用UDFs進行數(shù)據自動更新的教程

    UDFs即是MySQL的用戶自定義函數(shù)的縮寫,配合觸發(fā)器可以自動更新Memcached與MySql的數(shù)據,這里我們就來總結一下MySQL的源碼安裝及使用UDFs進行數(shù)據自動更新的教程:
    2016-07-07
  • MySQL到Kafka實時數(shù)據同步

    MySQL到Kafka實時數(shù)據同步

    很多 DBA 同學經常會遇到要從一個數(shù)據庫實時同步到另一個數(shù)據庫的問題,同構數(shù)據還相對容易,遇上異構數(shù)據、表多、數(shù)據量大等情況就難以同步,我自己親測了一種方式,可以非常方便的實現(xiàn)MySQL Kafka實時數(shù)據同步,需要的朋友可以參考下
    2024-01-01
  • MySql8 WITH RECURSIVE遞歸查詢父子集的方法

    MySql8 WITH RECURSIVE遞歸查詢父子集的方法

    這篇文章主要介紹了MySql8 WITH RECURSIVE遞歸查詢父子集的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-12-12
  • mysql 松散的索引掃描(Loose index scan)

    mysql 松散的索引掃描(Loose index scan)

    今天讀《High Performance MySQL》,發(fā)現(xiàn)一個“Loose index scan”,之前完全沒有聽說過。網上查了些資料,這個叫松散的索引掃描(Loose index scan)
    2016-05-05
  • MySQL低權限提權的方法

    MySQL低權限提權的方法

    在MySQL中,低權限提權是一種常見的需求,低權限用戶通過利用漏洞、存儲過程、用戶定義函數(shù)(UDF)和觸發(fā)器(Trigger)等技術手段進行權限提升,本文就來介紹一下,感興趣的可以了解一下
    2024-09-09
  • MySQL鎖機制與用法分析

    MySQL鎖機制與用法分析

    這篇文章主要介紹了MySQL鎖機制與用法,較為詳細的分析了mysql鎖機制的分類、原理及相關使用技巧,需要的朋友可以參考下
    2018-04-04
  • MySQL分表實現(xiàn)上百萬上千萬記錄分布存儲的批量查詢設計模式詳解

    MySQL分表實現(xiàn)上百萬上千萬記錄分布存儲的批量查詢設計模式詳解

    本篇文章是對使用MySQL分表實現(xiàn)上百萬上千萬記錄分布存儲的批量查詢設計模式進行了詳細的分析介紹,需要的朋友參考下
    2013-06-06

最新評論