天天看點

SpringCloud的分布式鎖和分布式事務

基于 Redis 的分布式鎖

利用 SETNX 和 SETEX

基本指令主要有:

SETNX(SET If Not Exists):當且僅當 Key 不存在時,則可以設定,否則不做任何動作。

SETEX:可以設定逾時時間

其原理為:通過 SETNX 設定 Key-Value 來獲得鎖,随即進入死循環,每次循環判斷,如果存在 Key 則繼續循環,如果不存在 Key,則跳出循環,目前任務執行完成後,删除 Key 以釋放鎖。

這種方式可能會導緻死鎖,為了避免這種情況,需要設定逾時時間。

通過資料庫實作分布式鎖是最不可靠的一種方式,對資料庫依賴較大,性能較低,不利于處理高并發的場景。

通過 Redis 的 Redlock 和 ZooKeeper 來加鎖,性能有了比較大的提升。

基于 Zookeeper 的分布式鎖

ZooKeeper 簡介

ZooKeeper 是一個分布式的,開放源碼的分布式應用程式協調服務,是 Google Chubby 的一個開源實作,是 Hadoop 和 Hbase 的重要元件。它是一個為分布式應用提供一緻性服務的軟體,提供的功能包括:配置維護、域名服務、分布式同步、組服務等。

針對 Redlock,曾經有位大神對其實作的分布式鎖提出了質疑,但是 Redis 官方卻不認可其說法,所謂公說公有理婆說婆有理,對于分布式鎖的解決方案,沒有最好,隻有最适合的,根據不同的項目采取不同方案才是最合理的。

首先我們應知道,事務是為了保證資料的一緻性而産生的。那麼分布式事務,顧名思義,就是我們要保證分布在不同資料庫、不同伺服器、不同應用之間的資料一緻性。

為什麼需要分布式事務?

最傳統的架構是單一架構,資料是存放在一個資料庫上的,采用資料庫的事務就能滿足我們的要求。随着業務的不斷擴張,資料的不斷增加,單一資料庫已經到達了一個瓶頸,是以我們需要對資料庫進行分庫分表。為了保證資料的一緻性,可能需要不同的資料庫之間的資料要麼同時成功,要麼同時失敗,否則可能導緻産生一些髒資料,也可能滋生 Bug。

在這種情況下,分布式事務思想應運而生。

應用場景

分布式事務的應用場景很廣,我也無法一一舉例,我列舉出比較常見的場景,以便于讀者在實際項目中,在用到了一些場景時即可考慮分布式事務。

支付

最經典的場景就是支付了,一筆支付,是對買家賬戶進行扣款,同時對賣家賬戶進行加錢,這些操作必須在一個事務裡執行,要麼全部成功,要麼全部失敗。而對于買家賬戶屬于買家中心,對應的是買家資料庫,而賣家賬戶屬于賣家中心,對應的是賣家資料庫,對不同資料庫的操作必然需要引入分布式事務。

線上下單

買家在電商平台下單,往往會涉及到兩個動作,一個是扣庫存,第二個是更新訂單狀态,庫存和訂單一般屬于不同的資料庫,需要使用分布式事務保證資料一緻性。

銀行轉賬

賬戶 A 轉賬到賬戶 B,實際操作是賬戶 A 減去相應金額,賬戶 B 增加相應金額,在分庫分表的前提下,賬戶 A 和賬戶 B 可能分别存儲在不同的資料庫中,這時需要使用分布式事務保證資料庫一緻性。否則可能導緻的後果是 A 扣了錢 B 卻沒有增加錢,或者 B 增加了錢 A 卻沒有扣錢。

SpringBoot 內建 Atomikos 實作分布式事務

Atomikos 簡介

Atomikos 是一個為 Java 平台提供增值服務的開源類事務管理器。

以下是包括在這個開源版本中的一些功能:

全面崩潰 / 重新開機恢複;

相容标準的 SUN 公司 JTA API;

嵌套事務;

為 XA 和非 XA 提供内置的 JDBC 擴充卡。

注釋:XA 協定由 Tuxedo 首先提出的,并交給 X/Open 組織,作為資料總管(資料庫)與事務管理器的接口标準。目前,Oracle、Informix、DB2 和 Sybase 等各大資料庫廠家都提供對 XA 的支援。XA 協定采用兩階段送出方式來管理分布式事務。XA 接口提供資料總管與事務管理器之間進行通信的标準接口。XA 協定包括兩套函數,以 xa_ 開頭的及以 ax_ 開頭的

繼續閱讀