天天看點

讀寫分離很難嗎?springboot結合aop簡單就實作了

目錄

前言

環境部署

開始項目

目錄結構

建表

主從資料源配置

設定路由

資料源的注解

aop切換資料源

注意

參考:

入職新公司到現在也有一個月了,完成了手頭的工作,前幾天終于有時間研究下公司舊項目的代碼。在研究代碼的過程中,發現項目裡用到了Spring Aop來實作資料庫的讀寫分離,本着自己愛學習(我自己都不信...)的性格,決定寫個執行個體工程來實作spring aop讀寫分離的效果。

資料庫:MySql

庫數量:2個,一主一從

關于mysql的主從環境部署之前已經寫過文章介紹過了,這裡就不再贅述,參考《手把手教你,如何在windows系統搭建mysql主從複制的環境》

首先,毫無疑問,先開始搭建一個SpringBoot工程,然後在pom檔案中引入如下依賴:

引入基本的依賴後,整理一下目錄結構,完成後的項目骨架大緻如下:

建立一張表user,在主庫執行sql語句同時在從庫生成對應的表資料

application.yml,主要資訊是主從庫的資料源配置

因為有一主一從兩個資料源,我們用枚舉類來代替,友善我們使用時能對應

資料源配置資訊類 DataSourceConfig,這裡配置了兩個資料源,masterDb和slaveDb

設定路由的目的為了友善查找對應的資料源,我們可以用ThreadLocal儲存資料源的資訊到每個線程中,友善我們需要時擷取

擷取路由

AbstractRoutingDataSource的作用是基于查找key路由到對應的資料源,它内部維護了一組目标資料源,并且做了路由key與目标資料源之間的映射,提供基于key查找資料源的方法。

為了可以友善切換資料源,我們可以寫一個注解,注解中包含資料源對應的枚舉值,預設是主庫,

到這裡,aop終于可以現身出場了,這裡我們定義一個aop類,對有注解的方法做切換資料源的操作,具體代碼如下:

到這一步,我們的準備配置工作就完成了,下面開始測試效果。

先寫好Service檔案,包含讀取和更新兩個方法,

根據方法上的注解可以看出,讀的方法走從庫,更新的方法走主庫,更新的對象是userId為<code>1196978513958141953</code> 的資料,

然後我們寫個測試類測試下是否能達到效果,

測試結果:

1、讀取方法

讀寫分離很難嗎?springboot結合aop簡單就實作了

2、更新方法

讀寫分離很難嗎?springboot結合aop簡單就實作了

執行之後,比對資料庫就可以發現主從庫都修改了資料,說明我們的讀寫分離是成功的。當然,更新方法可以指向從庫,這樣一來就隻會修改到從庫的資料,而不會涉及到主庫。

上面測試的例子雖然比較簡單,但也符合正常的讀寫分離配置。值得說明的是,讀寫分離的作用是為了緩解寫庫,也就是主庫的壓力,但一定要基于資料一緻性的原則,就是保證主從庫之間的資料一定要一緻。如果一個方法涉及到寫的邏輯,那麼該方法裡所有的資料庫操作都要走主庫。

假設寫的操作執行完後資料有可能還沒同步到從庫,然後讀的操作也開始執行了,如果這個讀取的程式走的依然是從庫的話,那麼就會出現資料不一緻的現象了,這是我們不允許的。

最後發一下項目的github位址,有興趣的同學可以看下,記得給個star哦

位址:https://github.com/Taoxj/mysql-proxy