亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

系統(tǒng)高吞吐量下的數(shù)據(jù)庫重復(fù)寫入問題分析解決

 更新時(shí)間:2022年04月22日 15:43:57   作者:zziawan  
這篇文章主要介紹了系統(tǒng)高吞吐量下的數(shù)據(jù)庫重復(fù)寫入問題分析解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

問題分析

為了提高系統(tǒng)的吞吐量,很多環(huán)節(jié)下對(duì)于數(shù)據(jù)庫的寫入是多線程,甚至是多進(jìn)程的。為了保證寫入成功,在很多情況下需要多次重試。這就會(huì)帶來一個(gè)問題,數(shù)據(jù)重復(fù),同一條數(shù)據(jù)會(huì)被記錄多次。有些情況下數(shù)據(jù)重復(fù)無傷大雅,但是很多情況系統(tǒng)是無法容忍數(shù)據(jù)重復(fù)的。因此這個(gè)問題需要解決。我個(gè)人覺得解決這一問題有兩個(gè)方向:第一,從數(shù)據(jù)庫上保證數(shù)據(jù)不重復(fù),第二,從程序上保證數(shù)據(jù)不重復(fù)。

數(shù)據(jù)庫上解決

主要包括:主鍵,唯一性索引,甚至是臨時(shí)表。程序上解決無非就是要保證同步,這兩種方式能解決很多情況下的數(shù)據(jù)重復(fù)。但是有些情況可能比較棘手,使用者兩種方法有時(shí)并不能很好的解決,或?qū)崿F(xiàn)起來比較復(fù)雜,如下面的數(shù)據(jù)

假如下表主要字段如下:

id  studentId  teacherId  states 

狀態(tài)(states)是有多種的(0,1,2,3),狀態(tài)可以轉(zhuǎn)換,但是狀態(tài)為,0的一個(gè)只能由一個(gè),其它字段是可以重復(fù)的。這個(gè)其實(shí)就是保證某一種狀態(tài)下的數(shù)據(jù)不重復(fù)。

首先唯一性索引不能夠起作用,因?yàn)闊o法建立唯一性索引。主鍵也沒有效果,沒法通過這些字段生成可區(qū)分的id。所以這兩種方法都失效了。還有一種方法就是臨時(shí)表,在臨時(shí)表中插入一條能夠區(qū)分的數(shù)據(jù)(比如studentId,teacherId組合),無論是唯一索引還是主鍵都可以。寫入時(shí)首先寫臨時(shí)表,臨時(shí)表寫入成功則插入一條數(shù)據(jù),然后清空臨時(shí)表。這在嚴(yán)格保證數(shù)據(jù)不重復(fù)的情況下是能夠起作用的,但是比較繁瑣,需要處理一個(gè)臨時(shí)表。

另外的一個(gè)辦法就是根據(jù)我們的業(yè)務(wù)場景,在一個(gè)時(shí)間段內(nèi)(比如1分鐘)不會(huì)出現(xiàn)兩條相同數(shù)據(jù)寫入。這樣我們可以使用studentIdTeacherid加上精確到分鐘的時(shí)間來構(gòu)成一個(gè)唯一id,重試時(shí)間間隔一般都極短(秒級(jí)別),這樣通過id來保證數(shù)據(jù)的唯一性。

從程序上保證數(shù)據(jù)不重復(fù)

如果從程序上來保證數(shù)據(jù)不重復(fù),則更加復(fù)雜。第一種辦法是對(duì)寫入過程加鎖,確保只有一次寫入成功代碼如下(偽代碼):

Lock lock =new WriteLock();
public void write(Data data){
try{
     if(lock.tryLock() ){
               dataRepository.save(data);
               if(dataRepository.numberOf(data)>1){//在寫入的時(shí)候檢測如果數(shù)據(jù)庫中有該數(shù)據(jù)拋出異常。再次保證數(shù)據(jù)不重復(fù)。
                   throw new DataException
            }
      
     }  
  }finally{
     lock.unlock();
  }
}

這種方式首先會(huì)存在效率問題,所有的數(shù)據(jù)都要順序?qū)懭霑?huì)導(dǎo)入效率下降。我們只需要保證同一條數(shù)據(jù)不能并發(fā)寫入而不是不同數(shù)據(jù)。另外這種方式還會(huì)存在一定概率的重復(fù),因?yàn)榫W(wǎng)絡(luò)問題和數(shù)據(jù)庫或ORM框架的緩存問題,會(huì)導(dǎo)致寫入檢測時(shí)并不能發(fā)現(xiàn)數(shù)據(jù)庫的更新。比如使用hibernate,兩次線程調(diào)用write方法會(huì)使用兩個(gè)session,從而使得第一次寫入緩存的數(shù)據(jù)無法在下一次操作中看到。在write方法中多次調(diào)用numberOf方法也是不起用的,由于session的緩存,后面的查詢會(huì)使用第一次的緩存結(jié)果,在第一次查詢后的數(shù)據(jù)庫變化,后面的查詢?nèi)匀粺o法覺察。

針對(duì)寫入效率低的問題,這里可以采用數(shù)據(jù)鎖,即通過一種方法比如使用data的hashcode來映射來獲取鎖,這樣不同的數(shù)據(jù)會(huì)獲取到不同的鎖,解決了所有數(shù)據(jù)的順序?qū)懭雴栴}。但是跟第一種情況一樣仍會(huì)存在數(shù)據(jù)重復(fù)問題。

對(duì)于多進(jìn)程的情況,如微服務(wù)部署多個(gè)的情況,上面的同步會(huì)失效。對(duì)于這種情況唯一的解決辦法就是使用上面所說的數(shù)據(jù)庫同步或者構(gòu)造一個(gè)環(huán)節(jié)鎖,類似于令牌的方法。只有獲取到令牌才有寫入資格,寫入成功后銷毀針對(duì)該數(shù)據(jù)的“令牌“。這種實(shí)現(xiàn)其實(shí)也比較簡單,如使用一個(gè)redis的hashmap,每次寫入首先獲取該數(shù)據(jù)對(duì)應(yīng)的value,通過value來判斷該數(shù)據(jù)是否寫入,來保證數(shù)據(jù)不重復(fù)。

總結(jié)

上面無論哪種方法,針對(duì)本文所提到的數(shù)據(jù),解決重復(fù)問題都是不容易的。要么實(shí)現(xiàn)起來比較復(fù)雜,要么還是不能100%保證數(shù)據(jù)不重復(fù)。針對(duì)我們的業(yè)務(wù)場景:state為0的狀態(tài)下數(shù)據(jù)能有一條,且0的狀態(tài)不會(huì)持續(xù)太久,后面的操作會(huì)將其修改。而且多線程重試并不是每次都發(fā)生的,多進(jìn)程情況下,每次數(shù)據(jù)寫入也多是只通過其中一個(gè)節(jié)點(diǎn),針對(duì)這種情況其實(shí)可以采取更簡單的處理方式,不做過多的順序限制只在寫入時(shí)檢查數(shù)據(jù)庫,如果真的因?yàn)閿?shù)據(jù)更新或者并發(fā)導(dǎo)致了多次寫入也沒有關(guān)系(這種情況很少),后續(xù)的操作時(shí)再刪除多寫入的數(shù)據(jù)。這是一種樂觀的處理方式,但是對(duì)于很多情況是可以解決數(shù)據(jù)重復(fù)問題的。

以上是我個(gè)人對(duì)于只有某種狀態(tài)的數(shù)據(jù)不能重復(fù)寫入問題的處理方法的思考。主要是從數(shù)據(jù)庫和程序上來控制及如果場景允許使用樂觀(后續(xù)補(bǔ)救)的方法。僅供參考,更多關(guān)于高吞吐量系統(tǒng)的數(shù)據(jù)庫重復(fù)寫入解決的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Navicat連接虛擬機(jī)mysql常見錯(cuò)誤問題及解決方法

    Navicat連接虛擬機(jī)mysql常見錯(cuò)誤問題及解決方法

    這篇文章主要介紹了Navicat連接虛擬機(jī)mysql常見錯(cuò)誤問題及解決方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-11-11
  • MySQL實(shí)現(xiàn)查詢處理JSON數(shù)據(jù)的示例詳解

    MySQL實(shí)現(xiàn)查詢處理JSON數(shù)據(jù)的示例詳解

    這篇文章主要為大家詳細(xì)介紹了MySQL如何實(shí)現(xiàn)查詢處理JSON數(shù)據(jù),文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的小伙伴可以了解一下
    2023-06-06
  • mysql中binlog_format模式與配置詳細(xì)分析

    mysql中binlog_format模式與配置詳細(xì)分析

    這篇文章主要介紹了mysql中binlog_format模式與配置的相關(guān)內(nèi)容,詳細(xì)介紹了binlog的三種格式與SBR、 RBR 兩種模式各自的優(yōu)缺點(diǎn),需要的朋友可以參考。
    2017-10-10
  • MySQL 8忘記密碼的最佳處理方式淺析

    MySQL 8忘記密碼的最佳處理方式淺析

    這篇文章主要給大家介紹了關(guān)于MySQL 8忘記密碼的處理方式,文中通過圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-02-02
  • mysql臟頁是什么

    mysql臟頁是什么

    本文主要介紹了什么是mysql臟頁,為什么會(huì)出現(xiàn)臟頁,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-07-07
  • MySQL開啟遠(yuǎn)程訪問權(quán)限的最新方法

    MySQL開啟遠(yuǎn)程訪問權(quán)限的最新方法

    這篇文章主要給大家介紹了關(guān)于MySQL開啟遠(yuǎn)程訪問權(quán)限的最新方法,在MySQL中,要實(shí)現(xiàn)遠(yuǎn)程訪問,首先需要在MySQL服務(wù)端上開啟相應(yīng)的權(quán)限,需要的朋友可以參考下
    2023-08-08
  • MySQL連接異常:Communications link failure問題及解決

    MySQL連接異常:Communications link failure問題及解決

    這篇文章主要介紹了MySQL連接異常:Communications link failure問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • MySql三種避免重復(fù)插入數(shù)據(jù)的方法

    MySql三種避免重復(fù)插入數(shù)據(jù)的方法

    這篇文章主要介紹了MySql三種避免重復(fù)插入數(shù)據(jù)的方法,幫助大家更好的理解和使用MySQL數(shù)據(jù)庫,感興趣的朋友可以了解下
    2020-09-09
  • MySQL中select...for update鎖表

    MySQL中select...for update鎖表

    select…for update在MySQL中,是一種悲觀鎖的用法,一般情況下,會(huì)鎖住一行數(shù)據(jù),但如果沒有使用正確的話,也會(huì)把整張表鎖住,本文就來介紹一下,感興趣的可以了解一下
    2023-10-10
  • MySQL修煉之聯(lián)結(jié)與集合淺析

    MySQL修煉之聯(lián)結(jié)與集合淺析

    在mysql中,最重要的就是查詢了,下面這篇文章主要給大家介紹了關(guān)于MySQL修煉之聯(lián)結(jié)與集合的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2021-09-09

最新評(píng)論