1 mysql如何實(shí)現(xiàn)事務(wù)的 acid,mysql事務(wù)的默認(rèn)隔離級(jí)別惧磺,如何解決幻讀
事務(wù)是一組 sql 語(yǔ)句颖对,是一個(gè)執(zhí)行單位。
事務(wù)的ACID特性
原子性(Atomicity):?jiǎn)蝹€(gè)事務(wù)的sql要么全部執(zhí)行成功磨隘,要么全部執(zhí)行失敗缤底。通過(guò) undo log 日志來(lái)實(shí)現(xiàn)顾患。在事務(wù)開(kāi)始之前,把要修改的記錄存到 undo日志里个唧,當(dāng)事務(wù)回滾或數(shù)據(jù)庫(kù)崩潰時(shí)江解,可以利用 undo 日志,撤銷(xiāo)事務(wù)對(duì)數(shù)據(jù)庫(kù)產(chǎn)生的影響徙歼。
持久性(Dutability):一個(gè)事務(wù)一旦提交犁河,它對(duì)數(shù)據(jù)庫(kù)的改變是永久的。通過(guò) redo log 日志來(lái)實(shí)現(xiàn)魄梯。事務(wù)中修改的任何數(shù)據(jù)呼股,都會(huì)將最新的值備份存儲(chǔ)到 Redo Log,在系統(tǒng) carsh 重啟后可通過(guò) redo log 來(lái)恢復(fù)數(shù)據(jù)画恰。
隔離性(Isolation):一個(gè)事務(wù)的執(zhí)行不能被其他事務(wù)干擾彭谁,即一個(gè)事務(wù)內(nèi)部的操作即使用的數(shù)據(jù)對(duì)其他并發(fā)的事務(wù)是隔離的。主要通過(guò)鎖和多版本控制技術(shù)(MVCC)來(lái)保證允扇。
一致性(Consisitency):一致性是一種約束缠局,是一種目的,在事務(wù)開(kāi)始之前和事務(wù)結(jié)束之后考润,數(shù)據(jù)庫(kù)的完整性不會(huì)被破壞狭园,包括約束一致性和數(shù)據(jù)一致性。它是原子性糊治,持久性唱矛,隔離性共同保證的結(jié)果。
事務(wù)隔離級(jí)別
隔離級(jí)別從低到高分別為:讀未提交井辜,讀已提交绎谦,可重復(fù)讀,串行化粥脚。
MySQL 默認(rèn)的隔離級(jí)別是可重復(fù)讀窃肠,公司的MySQL也是用的默認(rèn)設(shè)置。
可重復(fù)讀怎么實(shí)現(xiàn)的
可重復(fù)讀主要是通過(guò)事務(wù)的一致性視圖 和 數(shù)據(jù)的多版本控制技術(shù)(MVCC)來(lái)實(shí)現(xiàn)的刷允。
在可重復(fù)讀隔離級(jí)別下冤留,事務(wù)在啟動(dòng)時(shí)就會(huì)創(chuàng)建一個(gè)視圖,類似于拍了個(gè)照树灶,記錄該事務(wù)的事務(wù)id纤怒,數(shù)值,整個(gè)事務(wù)存在期間都用這個(gè)視圖天通。
數(shù)據(jù)的多版本控制技術(shù)(MVCC)指每行數(shù)據(jù)都可以有多個(gè)版本泊窘,每次事務(wù)修改數(shù)據(jù)后都會(huì)生成一個(gè)新的數(shù)據(jù)版本,數(shù)據(jù)版本里也會(huì)記錄事務(wù)的id,數(shù)值州既,同時(shí)會(huì)保留舊的數(shù)據(jù)版本谜洽,生成一條回滾日志萝映。
事務(wù)查詢數(shù)據(jù)時(shí)吴叶,都要根據(jù)最新的數(shù)據(jù)版本的當(dāng)前值,依次執(zhí)行圖中所有的回滾操作得到序臂。
什么是幻讀
一個(gè)事務(wù)在前后兩次查詢同一個(gè)范圍的時(shí)候蚌卤,后一次查詢看到了前一次查詢沒(méi)有看到的行。在可重復(fù)讀隔離級(jí)別下奥秆,普通的查詢是快照讀逊彭,是不會(huì)看到別的事務(wù)插入的數(shù)據(jù)的。因此构订,幻讀在“當(dāng)前讀”下才會(huì)出現(xiàn)侮叮。
幻讀有什么問(wèn)題
給所有的記錄都加上鎖,也阻止不了新插入的記錄悼瘾,無(wú)法保證數(shù)據(jù)一致性囊榜,同時(shí)數(shù)據(jù)和日志在邏輯上也會(huì)出現(xiàn)不一致。
如何解決幻讀
產(chǎn)生幻讀的原因是亥宿,行鎖只能鎖住行卸勺,但是新插入記錄這個(gè)動(dòng)作,要更新的是記錄之間的“間隙”烫扼。因此曙求,為了解決幻讀問(wèn)題革为,InnoDB 只好引入新的鎖聘鳞,也就是間隙鎖 (Gap Lock)。
間隙鎖的引入磷籍,可能會(huì)導(dǎo)致同樣的語(yǔ)句鎖住更大的范圍堰氓,引發(fā)死鎖芽淡,影響并發(fā)度。
有沒(méi)有更簡(jiǎn)單一點(diǎn)的處理方法呢豆赏?
間隙鎖是在可重復(fù)讀隔離級(jí)別下才會(huì)生效的挣菲。所以,如果把隔離級(jí)別設(shè)置為讀提交的話掷邦,就沒(méi)有間隙鎖了白胀。但同時(shí)要解決可能出現(xiàn)的數(shù)據(jù)和日志不一致問(wèn)題,需要把 binlog 格式設(shè)置為row抚岗。
binlog有兩種常用的格式或杠,一種是statement(默認(rèn)),一種是row宣蔚。
statement格式記錄的是我們執(zhí)行的sql向抢,而row格式記錄的則是實(shí)際受影響的數(shù)據(jù)的變化前后值认境。
3 如何優(yōu)化子查詢
4 mybatis的dao接口的工作原理是什么?
Dao 接口即 Mapper 接口挟鸠,接口的全限定名對(duì)應(yīng)于映射文件中 namespace 的值叉信,接口的方法名對(duì)應(yīng)于映射文件中每條 sql 的 id 值;接口方法內(nèi)的參數(shù)艘希,就是傳遞給 sql 的參數(shù)值硼身。
采用 Mapper 代理開(kāi)發(fā)方式時(shí),Mapper 接口是沒(méi)有實(shí)現(xiàn)類的覆享,當(dāng)調(diào)用接口方法時(shí)佳遂,接口全限名+方法名拼接字符串作為 key 值,可唯一定位一個(gè) MapperStatement撒顿。在 Mybatis 中丑罪,每一個(gè) <select>、<insert>凤壁、<update>吩屹、<delete>標(biāo)簽,都會(huì)被解析為一個(gè) MapperStatement 對(duì)象客扎。
每個(gè)Mybatis 運(yùn)行時(shí)會(huì)使用 JDK 動(dòng)態(tài)代理為 Mapper接口生成代理對(duì)象祟峦,代理對(duì)象去調(diào)用執(zhí)行方法,ResultHandler 將結(jié)果集進(jìn)行轉(zhuǎn)換徙鱼,返回最終的結(jié)果宅楞。
5 kafka 如何實(shí)現(xiàn)順序消費(fèi)
每條發(fā)布到 kafka 集群的消息都有一個(gè)主題,物理上不同主題的消息是分開(kāi)存儲(chǔ)的袱吆。
主題下還會(huì)分成多個(gè)分區(qū)厌衙,消息以追加的方式寫(xiě)入分區(qū),然后以先入先出的順序讀取绞绒,且每條消息只會(huì)存在某一個(gè)分區(qū)中婶希。
如果需要嚴(yán)格保證消息的消費(fèi)順序,需要將分區(qū)數(shù)目設(shè)為 1蓬衡,但是這樣做就丟失了 kafka 多分區(qū)帶來(lái)的高吞吐量和負(fù)載均衡的優(yōu)勢(shì)喻杈。
還有一種方式
發(fā)消息的時(shí)候,在消息體里根據(jù)不同的業(yè)務(wù)封裝不同的標(biāo)記位狰晚,并針對(duì)標(biāo)記位設(shè)定專門(mén)的分區(qū)策略筒饰,保證同一標(biāo)記位的所有消息都發(fā)送到同一分區(qū)。這樣既可以保證分區(qū)內(nèi)的消息順序壁晒,也可以享受到多分區(qū)帶來(lái)的性能優(yōu)勢(shì)瓷们。