一、事務的特性(ACID),原子性,一致性,隔離性,持久性;
二、Mysql的事務隔離級別
1、讀未已提交(READ UNCOMMITTED):
一個事務可以讀取到未提交的數據(比如只進行了更新操作),產生髒讀,幻度。
2、讀已提交(READ COMMITTED):
事務讀取到已經提交的數據,多次select,查詢結果不一致,產生幻度。
3、可重複讀(REPEATABLE READ) :
一個事務中多次讀取數據相同,可能產生幻讀,但是mysql的可重複讀解決了幻讀的問題,事務讀取可以分爲:快照讀使用與select 語句,比如:select id from user where id = 1 (MVCC:READVIEW 和 版本鏈解決)、當前讀,比如:select id from user where id = 1 for update (一個事務內讀取數據,間隙鎖),可以參考一下鏈接加深理解:https://blog.csdn.net/qq_40918324/article/details/104617714。
4、串行化(SERIALIZABLE):
三、1、 什麼是版本鏈:
在innoDB存儲引擎的表,有三個隱藏列分別是:row_id,trx_id,roll_pointer,其中row_id不是必要的,如果有主鍵索引,則列號不一定存在。
trx_id:記錄當前事務的事務號。
roll_pointer:指向前一個事務號,(通過指針找到修改前的記錄)。
2、ReadView:
① 對於讀已提交和可重複讀,需要使用上述的版本鏈,核心問題:找到哪個事務是正確的,可見的。那麼怎麼判斷哪個事務版本是可用的呢,就需要ReadView了,我發現其實很多人都在說mvcc但是卻不知道readView,真的是很奇怪。
② ReadView 主要由四部分組成:
1、m_ids:記錄當前活躍的所有事務,相當於一個數組,[1,2,3,4]
2、min_trx_id: 記錄當前活躍事務中最小的事務號。
3、max_trx_id:記錄下一個應該開啓的事務的事務號,事務號是遞增的,其實就是時間戳。
4、creator_trx_id:表示生成該ReadView的事務號。
④ 對於讀已提交和可重複讀,在生成ReadView的規則不同,導致了他們讀取數據時候的區別:
1、讀已提交:每次執行select的時候都會生成一個readView,記錄當前活躍的事務id。所以他可以讀取到最新的別提交過的數據。
2、可重讀度:他只會在第一次執行select 語句的時候生成ReadView,所以多次執行ReadView相同所以查詢數據相同。
四、mysql innoDB的行鎖與表鎖
一、行鎖:
1、行鎖分爲: ① LOCK_REC_NOT_GAP:單個行記錄上的鎖。
② LOCK_GAP:間隙鎖,只會鎖住查詢數據之間的間隙。
③ NEXT_KEY_LOCK:結合單行鎖和間隙鎖的鎖。
2、對於讀已提交,不存在間隙鎖,只會對錶中查詢出來的數據加鎖。
3、對於可重讀度,對於主鍵索引和二級索引不會加間隙鎖。對於普通索引和沒有索引的列,會對查詢出來的數據的間隙加鎖(可能會造成死鎖)。
4、這裏的鎖對於二級索引,首先會對索引字段加鎖,再下來同時會對,索引頁中的主鍵id進行加鎖,爲什麼會加兩次鎖?
① 當查詢數據有二級索引列時,直接判斷加鎖快速返回。
② 噹噹前查詢沒有二級索引列,但是時主鍵索引對應的數據時,保證數據被加鎖。