欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

問題分析

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

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

主要包括:主鍵,唯一性索引,甚至是臨時表。程序上解決無非就是要保證同步,這兩種方式能解決很多情況下的數(shù)據(jù)重復(fù)。但是有些情況可能比較棘手,使用者兩種方法有時并不能很好的解決,或?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的一個只能由一個,其它字段是可以重復(fù)的。這個其實就是保證某一種狀態(tài)下的數(shù)據(jù)不重復(fù)。

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

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

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

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

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

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

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

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

總結(jié)

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

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

相關(guān)文章

  • Navicat連接虛擬機mysql常見錯誤問題及解決方法

    Navicat連接虛擬機mysql常見錯誤問題及解決方法

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

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

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

    mysql中binlog_format模式與配置詳細分析

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

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

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

    mysql臟頁是什么

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

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

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

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

    這篇文章主要介紹了MySQL連接異常:Communications link failure問題及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    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中,是一種悲觀鎖的用法,一般情況下,會鎖住一行數(shù)據(jù),但如果沒有使用正確的話,也會把整張表鎖住,本文就來介紹一下,感興趣的可以了解一下
    2023-10-10
  • MySQL修煉之聯(lián)結(jié)與集合淺析

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

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

最新評論