1 什么是消息的冪等性
如果同一個消息,因為各種原因,不慎被消費了多次(例如多次點按按鈕),和只消費一次得到的數據是相同的。就可以說保持了冪等性。
如果我們不人為保證消息的冪等性,數據就會出錯。可以通過樂觀鎖、悲觀鎖等方式保證消息的等冪性。
2 樂觀鎖與悲觀鎖
樂觀鎖是一種教寬松的鎖機制,在線程進行數據更新之前對當前的數據版本進行比對,如果版本相同則允許進行操作。
悲觀鎖是一種較嚴格的鎖機制,即悲觀的認為每個線程在更新數據的時候都會被其他線程修改數據。為了防止這種情況,在一個線程需要操作數據時,先取鎖再操作。
3 樂觀鎖
3.1 樂觀鎖之CAS
CAS即CompareAndSwap(比較和交換)。
當希望更新一條數據的時候,將原始的數據也一起取出來。最終進行更新的時候,將取出的原始數據和現在數據庫中的數據進行比較,如果相同,則進行操作。
例如:數據庫中有一條用戶信息的用戶名為Tom,需要變更為Tony。生產者在生產消息時,消息中就攜帶着原始的用戶名Tom。當消費者進行更新操作前,將Tom和當前數據庫中的用戶名進行比較,
相同才進行更新操作。
3.2 CAS的缺點
雖然能夠實現樂觀鎖,但CAS方式並不是完美的,也存在一些缺點。
ABA問題
還是以修改用戶名為例,理想中的CAS流程是這樣的:
而實際的流程卻可能是這樣的:
在取出數據與更新數據的間隔之間,數據已經被修改過了。
現實中的類似的情況就是,保險櫃里有10W塊錢。財務人員監守自盜,拿着10W元去買彩票。中獎之后又往保險櫃里放了10W元。雖然前后金額沒有變化,但卻是存在安全隱患的。
3.3 樂觀鎖之版本號
版本號機制本質還是CAS,但通過給變量攜帶一個版本號,規避了ABA問題。
版本號可以使用一個自增的數字,也可以使用時間戳。
4 悲觀鎖
悲觀鎖主要依靠關系型數據庫的鎖機制。悲觀鎖又分為共享鎖和排它鎖。
4.1 共享鎖
共享鎖又稱為讀鎖。多個事務可以共享一個讀鎖,對數據進行讀取。
4.2 排它鎖
排它鎖又稱為寫鎖。只有一個事務可以獲取到寫鎖。其他事務要等待獲取到寫鎖才可以對數據進行更新操作。