分布式應用併發解決方案以及注意事項

2021-09-21 07:21:39 字數 1072 閱讀 5722

背景

現在大部分應用差不多都是微服務架構,服務之間至少是雙節點,那麼就會出現併發的場景。舉個例子,支付當中的賬務服務,部署了雙節點,同乙個商戶同一時刻有多筆訂單入賬,兩台服務收到請求的概率相同,這時候我們就需要考慮併發問題。下面將闡述如何去解決。

核心**主要業務邏輯:

1、查詢賬戶(非必要)

2、獲取賬戶鎖(同步鎖,如果獲取不到將一直等待)

3、重新查詢賬戶,目的是獲取最新值(初衷很美好)

4、根據當前業務邏輯更新賬戶資訊,如操作餘額

5、釋放鎖

主要風險點:

1、鎖是否真生效,如何判斷是否真實生效,同一key,同一時刻,兩個節點是否能同時拿到鎖,分布式鎖實現方案也有多種選擇,如借助redis、zookkeeper。

2、第三步中的查詢結果是否真的為最新值,即資料庫中最新的值。這裡需要注意兩個地方,乙個是資料庫事務中的可重複讀,如果有第一步,如在第三步查詢時沒有開啟新的事務去查詢,那麼很有可能查的是髒資料,順便說一下,mysql預設的隔離級別是可重複讀,如果不太了解這個知識,建議深入了解一下。另乙個是orm框架中是否存在快取,如mybatis的一級快取,hibernate的一級快取,切記勿入坑。

3、釋放鎖,操作完之後,不管是成功或者異常,一定要釋放鎖,不然別的執行緒一直在等待,非常致命。

更加可靠的方案:

資料庫底層控制,加樂觀鎖(如不明白可深入了解),如上面在賬戶表中加一新列,類似版本號的東西,每次更新帶上版本號並累加(update 餘額 , 版本號=版本號+1 where 版本號=版本 and 條件)。

優化之後的邏輯步驟:

1、查詢賬戶(非必要)

2、獲取賬戶鎖(同步鎖,如果獲取不到將一直等待)

3、重新查詢賬戶,目的是獲取最新值(初衷很美好)

4、根據當前業務邏輯更新賬戶資訊,更新賬戶的時候把版本號作為條件,每次更新時版本號隨之公升級,如果未更新到資料,則丟擲異常,整個邏輯會進行回滾。

5、釋放鎖

結束語:

如果資料庫底層加上了樂觀鎖,即使分布式鎖出現問題,或者出現了可重複讀的問題,最後依然可以避免因為並發出問題,但分布式鎖、獲取鎖之後的查詢依然是必要的,如果出現了太多的異常回滾,對效能會有損耗。

分布式事務解決方案

一 結合mq訊息中介軟體實現的可靠訊息最終一致性 二 tcc補償性事務解決 三 最大努力通知型方案 第一種方案 可靠訊息最終一致性,需要業務系統結合mq訊息中介軟體實現,在實現過程中需要保證訊息的成功傳送及成功消費。即需要通過業務系統控制mq的訊息狀態 第二種方案 tcc補償性,分為三個階段tryi...

分布式事務解決方案

當資料庫單錶一年產生的資料超過1000w,那麼就要考慮分庫分表,具體分庫分表的原理在此不做解釋,以後有空詳細說,簡單的說就是原來的乙個資料庫變成了多個資料庫。這時候,如果乙個操作既訪問01庫,又訪問02庫,而且要保證資料的一致性,那麼就要用到分布式事務。所謂的soa化,就是業務的服務化。比如原來單機...

分布式事務解決方案

由於資料量的巨大,大部分web應用都需要部署很多個資料庫例項。這樣,有些使用者操作就可能需要去修改多個資料庫例項中的資料。傳統的解決方法是使用分布式事務保證資料的全域性一致性,經典的方法是使用兩階段提交協議。長期以來,分布式事務提供的優雅的全域性acid保證麻醉了應用開發者的心靈,很多人都不敢越雷池...