一、為什么一個(gè)事務(wù)能讀取到其他事務(wù)修改后未提交的數(shù)據(jù)
在沒(méi)有正式提交之前,數(shù)據(jù)是先更新到日志之中的,只有commit提交之后,才真正再?gòu)娜罩局懈碌絤ysql表中。你不用去糾結(jié)為什么能讀到它。你只需知道,是事務(wù)與事務(wù)并發(fā)進(jìn)行時(shí),是具有影響性的,這種影響性的大小被稱為隔離級(jí)別。那怎么防止未提交讀呢?就是加寫(xiě)鎖,然后提交之后釋放鎖,在這個(gè)時(shí)候,mysql的隔離級(jí)別就變成了已提交讀。而加鎖,釋放鎖是由mysql自動(dòng)完成的,你無(wú)需關(guān)心。所以,其實(shí)本質(zhì)上是鎖的應(yīng)用,最終導(dǎo)致了不同的隔離級(jí)別,不同的隔離級(jí)別,鎖的應(yīng)用也不同。
“數(shù)據(jù)未提交,那數(shù)據(jù)庫(kù)應(yīng)該沒(méi)有改變”,這個(gè)假設(shè)其實(shí)是錯(cuò)誤的。數(shù)據(jù)庫(kù)的底層設(shè)計(jì)都使用了WAL(Write-ahead**Logging)思想,只不過(guò)數(shù)據(jù)庫(kù)的事務(wù)隔離技術(shù)了提供了各種方案,一個(gè)數(shù)據(jù)庫(kù)請(qǐng)求即使事務(wù)沒(méi)有提交也會(huì)發(fā)生數(shù)據(jù)庫(kù)內(nèi)部數(shù)據(jù)的變更,有各種技術(shù),像Mysql InnoDB MVCC,只不過(guò)是通過(guò)一些字段進(jìn)行控制。
在數(shù)據(jù)庫(kù)沒(méi)有提交數(shù)據(jù)的時(shí)候,你更新的數(shù)據(jù)是在緩存進(jìn)行更新的,事務(wù)與事務(wù)在并發(fā)進(jìn)行的時(shí)候就叫作隔離級(jí)別,只有在提交之后,數(shù)據(jù)才從日志中把數(shù)據(jù)更新到數(shù)據(jù)庫(kù)里面。
目前主流的關(guān)系型數(shù)據(jù)庫(kù)例如mysql、Oracle都是基于文件系統(tǒng)進(jìn)行數(shù)據(jù)存儲(chǔ)的,即數(shù)據(jù)是持久化到文件系統(tǒng)的,但基于文件系統(tǒng)的隨機(jī)IO讀寫(xiě)是非常慢的,故數(shù)據(jù)庫(kù)都會(huì)引入內(nèi)存池,完成對(duì)磁盤(pán)數(shù)據(jù)的緩存,提高讀寫(xiě)性能。內(nèi)存池是對(duì)所有線程共享的,也就是對(duì)所有的數(shù)據(jù)庫(kù)事務(wù)是共享的,所謂的未提交,指的是事務(wù)未提交,但此時(shí)數(shù)據(jù)已經(jīng)存儲(chǔ)到了共享內(nèi)存中,數(shù)據(jù)已經(jīng)進(jìn)入到了數(shù)據(jù)庫(kù)服務(wù)器中,所以是可見(jiàn)的。
延伸閱讀:
二、MongoDB是什么
非關(guān)系型數(shù)據(jù)庫(kù)(nosql ),屬于文檔型數(shù)據(jù)庫(kù)。MongoDB采用類JSON的documents來(lái)存儲(chǔ)數(shù)據(jù)。數(shù)據(jù)結(jié)構(gòu)由鍵值(key=>value)對(duì)組成。
MongoDB采用動(dòng)態(tài)數(shù)據(jù)模型schema,這意味著不需要預(yù)先定義表的數(shù)據(jù)類型和字段名。當(dāng)MongoDB需要更新文檔documents的時(shí)候,可以輕松增加新的字段名或者刪除舊的字段。MongoDB讓數(shù)據(jù)結(jié)構(gòu)更加層級(jí)化,因而存儲(chǔ)數(shù)組等復(fù)雜數(shù)據(jù)結(jié)構(gòu)。 在同一個(gè)集合collection中,文檔document對(duì)字段也沒(méi)有強(qiáng)約束,因此更容易設(shè)計(jì)差異化的數(shù)據(jù)結(jié)構(gòu)。