資源描述:
《大數(shù)據(jù)下高并發(fā)的處理詳解》由會(huì)員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在應(yīng)用文檔-天天文庫。
1、大數(shù)據(jù)下高并發(fā)的處理詳解本文章來自于阿里云云棲社區(qū)對(duì)于我們開發(fā)的網(wǎng)站,如果網(wǎng)站的訪問量非常大的話,那么我們就需要考慮相關(guān)的并發(fā)訪問問題了。而并發(fā)問題是絕大部分的程序員頭疼的問題,但話又說回來了,既然逃避不掉,那我們就要想想應(yīng)對(duì)措施,今天我們就一起討論一下常見的并發(fā)和同步吧。首先為了更好的理解并發(fā)和同步,我們需要首先明白兩個(gè)重要的概念:同步和異步同步和異步的區(qū)別和聯(lián)系所謂同步,就是一個(gè)線程執(zhí)行一個(gè)方法或函數(shù)的時(shí)候,會(huì)阻塞其它線程,其他線程要等待它執(zhí)行完畢才能繼續(xù)執(zhí)行。異步,就是多個(gè)線程之間沒有阻塞,多個(gè)線程同時(shí)執(zhí)行。通俗一點(diǎn)來說,同步就是一件事一件事的做
2、,異步就是做一件事,不影響做其他事情。例如:吃飯和說話,只能一件一件的來,因?yàn)橹挥幸粡堊?。但是吃飯和聽音樂是異步的,可以一起進(jìn)行,因?yàn)槁犚魳凡⒉挥绊懳覀兂燥?。?duì)于Java程序員來說,Synchronized最為熟悉了,如果它作用于一個(gè)類的話,那么就是一個(gè)線程訪問類的方法時(shí),其他線程就會(huì)阻塞,相反,如果沒有這個(gè)關(guān)鍵字來修飾的話,不同線程就可以在同一時(shí)間訪問同一個(gè)方法,這就是異步。臟讀和不可重復(fù)讀臟讀臟讀就是指當(dāng)一個(gè)事務(wù)正在訪問數(shù)據(jù),并且對(duì)數(shù)據(jù)進(jìn)行了修改,而這種修改還沒有提交到數(shù)據(jù)庫中,這是,另外一個(gè)事務(wù)也訪問這個(gè)數(shù)據(jù),然后使用了這個(gè)數(shù)據(jù)。因?yàn)檫@個(gè)數(shù)據(jù)是還
3、沒有提交的數(shù)據(jù),那么另外一個(gè)事務(wù)讀取的這個(gè)數(shù)據(jù)是臟數(shù)據(jù)(DirtyData),依據(jù)臟數(shù)據(jù)所做的操作可能是不正確的。不可重復(fù)讀在第一個(gè)事務(wù)讀取數(shù)據(jù)后,第二個(gè)事務(wù)對(duì)數(shù)據(jù)進(jìn)行了修改,導(dǎo)致第一個(gè)事務(wù)結(jié)束前再訪問這個(gè)數(shù)據(jù)的時(shí)候,會(huì)發(fā)現(xiàn)兩次讀取到的數(shù)據(jù)是不一樣的,因此稱為不可重復(fù)讀。如何處理并發(fā)和同步今天講的如何處理并發(fā)和同同步問題主要是通過鎖機(jī)制。我們需要明白,鎖機(jī)制有兩個(gè)層面。一種是代碼層次上的,如果Java中的同步鎖Synchronized,另一種是數(shù)據(jù)庫層次上的,比較典型的就是悲觀鎖(傳統(tǒng)的物理鎖)和樂觀鎖悲觀鎖悲觀鎖,正如其名,它指的是對(duì)數(shù)據(jù)被外界(包括
4、本系統(tǒng)當(dāng)前的其他事務(wù),以及來自外部系統(tǒng)的事務(wù)處理)修改持保守態(tài)度。因此,在這個(gè)數(shù)據(jù)處理過程中,將數(shù)據(jù)處于鎖定狀態(tài)。悲觀鎖的實(shí)現(xiàn),往往依靠數(shù)據(jù)庫提供的鎖機(jī)制(也只有數(shù)據(jù)庫層提供的鎖機(jī)制才能真正保證數(shù)據(jù)訪問的排他性,否則,即使在本系統(tǒng)中實(shí)現(xiàn)了加鎖機(jī)制,也無法保證外部系統(tǒng)不會(huì)修改數(shù)據(jù))。一個(gè)典型的倚賴數(shù)據(jù)庫的悲觀鎖調(diào)用:select*fromaccountwherename=”Erica”forupdate這條sql語句鎖定了account表中所有符合檢索條件(name=”Erica”)的記錄。本次事務(wù)提交之前(事務(wù)提交時(shí)會(huì)釋放事務(wù)過程中的鎖),外界無法修改
5、這些記錄。Hibernate的悲觀鎖,也是基于數(shù)據(jù)庫的鎖機(jī)制實(shí)現(xiàn)。下面的代碼實(shí)現(xiàn)了對(duì)查詢記錄的加鎖:1234StringhqlStr="fromTUserasuserwhereuser.name='Erica'";Queryquery=session.createQuery(hqlStr);query.setLockMode("user",LockMode.UPGRADE);//加鎖ListuserList=query.list();//執(zhí)行查詢,獲取數(shù)據(jù)觀察運(yùn)行期Hibernate生成的SQL語句:1selecttuser0_.idasid,tuse
6、r0_.nameasname,tuser0_.group_idasgroup_id,tuser0_.user_typeasuser_type,tuser0_.sexassexfromt_usertuser0_where(tuser0_.name='Erica')forupdate這里Hibernate通過使用數(shù)據(jù)庫的forupdate子句實(shí)現(xiàn)了悲觀鎖機(jī)制。Hibernate的加鎖模式有:123456789101LockMode.NONE:無鎖機(jī)制。LockMode.WRITE:Hibernate在Insert和Update記錄的時(shí)候會(huì)自動(dòng)獲取LockM
7、ode.READ:Hibernate在讀取記錄的時(shí)候會(huì)自動(dòng)獲取。以上這三種鎖機(jī)制一般由Hibernate內(nèi)部使用,如Hibernate為了保證Update過程中對(duì)象不會(huì)被外界修改,會(huì)在save方法實(shí)現(xiàn)中自動(dòng)為目標(biāo)對(duì)象加上WRITE鎖。LockMode.UPGRADE:利用數(shù)據(jù)庫的forupdate子句加鎖。LockMode.UPGRADE_NOWAIT:Oracle的特定實(shí)現(xiàn),利用Oracle的forupdatenowait子句實(shí)現(xiàn)加鎖。上面這兩種鎖機(jī)制是我們?cè)趹?yīng)用層較為常用的,加鎖一般通過以下方法實(shí)現(xiàn):Criteria.setLockMode112Q
8、uery.setLockModeSession.lock注意,只有在查詢開始之前(也就是Hib