目錄
前言
環境部署
開始項目
目錄結構
建表
主從資料源配置
設定路由
資料源的注解
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、讀取方法

2、更新方法
執行之後,比對資料庫就可以發現主從庫都修改了資料,說明我們的讀寫分離是成功的。當然,更新方法可以指向從庫,這樣一來就隻會修改到從庫的資料,而不會涉及到主庫。
上面測試的例子雖然比較簡單,但也符合正常的讀寫分離配置。值得說明的是,讀寫分離的作用是為了緩解寫庫,也就是主庫的壓力,但一定要基于資料一緻性的原則,就是保證主從庫之間的資料一定要一緻。如果一個方法涉及到寫的邏輯,那麼該方法裡所有的資料庫操作都要走主庫。
假設寫的操作執行完後資料有可能還沒同步到從庫,然後讀的操作也開始執行了,如果這個讀取的程式走的依然是從庫的話,那麼就會出現資料不一緻的現象了,這是我們不允許的。
最後發一下項目的github位址,有興趣的同學可以看下,記得給個star哦
位址:https://github.com/Taoxj/mysql-proxy