高併發下如何對數據庫進行更新操作

問題:

        在高併發的系統下,對數據庫進行更行時,如果沒有防重機制做攔截,就會導致數據被更新多次,從而影響更新後程序的後續操作。


解決方案:

方案一:

方案詳情:加鎖查詢攔截,在更新前,加鎖(分佈式系統用分佈式鎖、也可用數據庫鎖等),查詢需要更新的數據是否存在且未被                    更新,根據查詢結果做更新操作,更新後釋放鎖;

適用情況:對數據需要進行多次更新,或多箇中間狀態都可以對數據進行操作;

方案優勢:保證數據更新的一致性;

方案缺點:系統性能消耗大,鎖機制影響系統的效率;

僞代碼示例:

//本示例以分佈式系統爲例,單系統下直接使用Lock或synchronized鎖即可
eg:

    // 用redis加鎖
    redis.set(key, value);

    // 查詢要更新的數據
    int result = select * from table where 條件;

    // 更新操作
    if(result == 1){
        //判斷數據是否已經被更新
        if(未被更行){
            //更新
            update table set XXX=x2 where 條件;
        }
    }

    // 釋放鎖
    redis.del(key);

方案二(推薦):

方案詳情:數據庫層面攔截,直接在更新數據時帶狀態更新數據,根據更新後成功與否做後續操作;

適用情況:明確知道更新數據前或後的狀態,且不會在更新時多次發生狀態變化,保證前後一致性;

方案優勢:簡單,保證數據更新的一致性,且對效率影響較小;

方案缺點:系統性能消耗大,鎖機制影響系統的效率;

僞代碼示例:

// 數據庫層的sql語句限制即可
int result = update table set 更新的內容 where 原數據的內容  != 更新的內容;

//  更新成功
if(result == 1){

    // 執行更新成功後的操作
    
}else{

    // 執行更新失敗後的操作

}

            
原因:

     高併發的情況下,多個請求對同一條數據進行更新操作,易導致數據被多次更新,影響數據庫的正確性;

 

相關知識點:

      1.sql語句;

      2.分佈式鎖;


代碼示例:

     如解決方案中的僞代碼示例。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章