這段時(shí)間趁著工作不忙,一起來回顧一下Mybatis+mysql的一些底層?xùn)|西
?
一、mysql
?1:mysql鎖有哪些?---》共享鎖(讀鎖)和排他鎖(寫鎖)
? ?1):共享鎖(通過 lock in share model實(shí)現(xiàn))
? ? ? 共享鎖又叫讀鎖,也就是執(zhí)行一條查詢sql語句的時(shí)候?qū)崿F(xiàn)的,一旦共享鎖,此時(shí)查詢的數(shù)據(jù)被鎖定,不能被其他事務(wù)進(jìn)行寫操作
? ?2):排它鎖(寫鎖)
? ? ? ? ?個(gè)人對排它鎖定義:排它鎖就是對數(shù)據(jù)鎖定,很大程度上講數(shù)據(jù)不能被其他事務(wù)修改(個(gè)人理解,僅關(guān)參考)
? ? ? ? ?正解:排它鎖又分為表級(jí)鎖和行級(jí)鎖,下面詳細(xì)講解這兩個(gè)鎖的作用:
? ? ?2.1)表級(jí)鎖:一旦事務(wù)使用的是表級(jí)鎖,那么整個(gè)表的數(shù)據(jù)不能被讀取以及修改,一般是不會(huì)這么操作。
? ? ?2.2)行級(jí)鎖:行級(jí)鎖的作用就是事務(wù)開啟,鎖定當(dāng)前讀取的行數(shù)據(jù)不能被修改或者通過版本號(hào)控制修改成功或失?。▊€(gè)人總結(jié),僅供參考)
? ? ? ? ?正解:行級(jí)鎖又分為樂觀鎖,悲觀鎖,下面詳細(xì)講解:
? ? ?2.2.1)悲觀鎖(通過for update 實(shí)現(xiàn)):悲觀鎖的含義就是事務(wù)開啟使用悲觀鎖,此時(shí)讀取的行數(shù)據(jù),不能被修改
? ? ? ? ? ? ? ? 示范sql:select * from user where id=1 for update;
?
? ? ?2.2.2)樂觀鎖:樂觀鎖的話是允許其他事務(wù)讀取或者修改,但是修改成功與否通過版本號(hào) version 來控制
? ??
二:事務(wù)的隔離性和隔離級(jí)別---相信大家都知道的,但是因?yàn)樾枰v解其他內(nèi)容,必須引入這該死的簡單東西
? 隔離特性:
? ? 原子性? -? -? 要么全部失敗,要么全部成功
? ? 一致性? -? -? 一般用在轉(zhuǎn)賬,A賬戶扣1000,轉(zhuǎn)到B賬戶,B賬戶增加1000
? ?隔離性? ?-? -? 一個(gè)事物正在處理的數(shù)據(jù),其他事務(wù)不能看見
? ?持久性? ?-? -? 數(shù)據(jù)一旦保存到數(shù)據(jù)庫,那么數(shù)據(jù)永久保存
?隔離級(jí)別:
? ? 1-讀未提交
? ? ? ? ?比如兩個(gè)事物A、B。事物A在讀取的數(shù)據(jù),正好是事物B正在修改但是未commit事物的用戶的名字 張三-->李四,然后此時(shí)事物B出現(xiàn)程序錯(cuò)誤,但是A讀取的是李四來操作數(shù)據(jù),這就是幻讀(后面講解MVCC+間隙鎖來解決幻讀)
?
? ? 2-讀已提交
? ? ? ??比如兩個(gè)事物A、B。事物A在第一次讀取在讀取用戶表id=1的數(shù)據(jù)是張三,正好此時(shí)事物B正在修改并且提交了事物(commit)commit事物的用戶的名字 張三-->李四,某些情況下事物A再查詢一遍是否是張三,但是事物B已經(jīng)修改并且提交,此時(shí)事物A讀取到的是李四,這就是兩次讀取的結(jié)果不一致
?
? ? 3-可重復(fù)復(fù)讀
? ? ? ? mysql的默認(rèn)隔離級(jí)別,每次讀取的結(jié)果都一樣,但是會(huì)產(chǎn)生幻讀(MVCC+間隙鎖解決)
? ? 4-串行?
? ? ? ?該種隔離級(jí)別一般不會(huì)使用,因?yàn)闀?huì)給每一行數(shù)據(jù)都會(huì)加鎖,導(dǎo)致大量的超時(shí)鎖和鎖鎖競爭問題
?
三:ACID如何保證?
? ?A:原子性 ——數(shù)據(jù)庫有undo log日志。記錄需要回滾的日志信息。事務(wù)回滾時(shí)撤銷已經(jīng)成功執(zhí)行的sql
? C:一致性——使用代碼保證(一般都是用try cay語句的咯,并且方法上加上@Transtal(level=Excetion.class))
? ?I :隔離性 —— MVCC(詳細(xì)講解MVCC傳送們)
? D:持久性 —— 內(nèi)存+redo log日志。sql執(zhí)行的時(shí)候,commit事務(wù)后,會(huì)通過redo log刷盤,宕機(jī)的時(shí)候,可以通過redo log恢復(fù)。
?
四:MVCC是什么?如何解決幻讀
?
?
九:mybatis 的編譯原理以及執(zhí)行原理
? ? ?1、編譯原理:看下圖,整體流程就不用文字描述,相信大伙能看懂!
? ? ? ??
? 2:執(zhí)行原理--照樣看圖比較直觀(大致流程大伙應(yīng)該能看得懂,要是還看不懂,那就gg了)
?
?
?
十、mybatis的組成結(jié)構(gòu)圖
?
十一、?mybatis的exectory執(zhí)行器有哪些,有哪些區(qū)別?
? 我們能看到第十點(diǎn)的mybatis總結(jié)架構(gòu)圖,第二組成部分的 SQL執(zhí)行,里面包含3種執(zhí)行器:下面詳細(xì)說:
?SimpleExectory執(zhí)行器:執(zhí)行select和update的sql語句,每次執(zhí)行sql,都會(huì)創(chuàng)建Statement對象,用完就關(guān)閉
?
?RuseExectory執(zhí)行器:執(zhí)行select和update的sql語句,它的區(qū)別在于使用執(zhí)行的sql作為key,在Map<String,Statement>做緩存,如果沒有,則創(chuàng)建Statement對象,并且緩存到Map<String,Statement>里面,用完不關(guān)閉Statement對象
?
?BatchExectory執(zhí)行器:只執(zhí)行update語句(JDBC不支持批量查詢),將sql添加到 addBatch()中,等待統(tǒng)一執(zhí)行 exectoryBatch()。它緩存了多個(gè)Statement對象
?
十二、mybatis為啥要預(yù)編譯處理?
我們首先了解預(yù)編譯處理的好處:JDBC使用PrestateStatement 來抽象預(yù)編譯sql語句,預(yù)編譯后可以優(yōu)化sql語句,并且一般都能夠直接執(zhí)行,所以DBMS(mysql、SQL或其他數(shù)據(jù)庫不需要再進(jìn)行預(yù)編譯處理),并且預(yù)編譯的語句對象可重復(fù)利用,即 PrepareStatement 對象緩存下載
?
?
?
?
?
本文摘自 :https://blog.51cto.com/u