婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > Spring AOP切面解決數據庫讀寫分離實例詳解

Spring AOP切面解決數據庫讀寫分離實例詳解

熱門標簽:電話機器人需要使用網絡嗎 南通通訊外呼系統產品介紹 自繪地圖標注數據 電銷機器人免培訓 如何看懂地圖標注點 潤滑油銷售電銷機器人 海外圖書館地圖標注點 外呼系統使用方法 給地圖標注得傭金

Spring AOP切面解決數據庫讀寫分離實例詳解

為了減輕數據庫的壓力,一般會使用數據庫主從(master/slave)的方式,但是這種方式會給應用程序帶來一定的麻煩,比如說,應用程序如何做到把數據寫到master庫,而讀取數據的時候,從slave庫讀取。如果應用程序判斷失誤,把數據寫入到slave庫,會給系統造成致命的打擊。

解決讀寫分離的方案很多,常用的有SQL解析、動態設置數據源。SQL解析主要是通過分析sql語句是insert/select/update/delete中的哪一種,從而對應選擇主從。而動態設置數據源,則是通過攔截方法名稱的方式來決定主從的,例如:save*(),insert*() 形式的方法使用master庫,select()開頭的,使用slave庫。蠻多公司會使用在方法上標上自定義的@Master、@Slave之類的標簽來選擇主從,也有公司直接就調用setxxMaster,setxxSlave之類的代碼進行主從選擇。

下面我主要介紹一下基于Spring AOP動態設置數據源這種方式。注意這篇文章是基于自己項目的實際情況的,不是通用的方案,請知曉。

原理圖


 

Spring AOP的切面主要的職責是攔截Mybatis的Mapper接口,通過判斷Mapper接口中的方法名稱來決定主從。

 Spring AOP 切面配置

aop:config expose-proxy="true"> 
 
aop:pointcut id="txPointcut" expression="execution(* com.test..persistence..*.*(..))" /> 
 
aop:aspect ref="readWriteInterceptor" order="1"> 
 
aop:around pointcut-ref="txPointcut" method="readOrWriteDB"/> 
 
/aop:aspect> 
 
/aop:config> 
 
  
 
bean id="readWriteInterceptor" class="com.test.ReadWriteInterceptor"> 
 
  property name="readMethodList"> 
 
   list> 
 
    value>query*/value> 
 
    value>use*/value> 
 
    value>get*/value> 
 
    value>count*/value> 
 
    value>find*/value> 
 
    value>list*/value> 
 
    value>search*/value> 
 
  /list> 
 
 /property> 
 
property name="writeMethodList"> 
 
  list> 
 
    value>save*/value> 
 
    value>add*/value> 
 
    value>create*/value> 
 
    value>insert*/value> 
 
    value>update*/value> 
 
    value>merge*/value> 
 
    value>del*/value> 
 
    value>remove*/value> 
 
    value>put*/value> 
 
    value>write*/value> 
 
  /list> 
 
/property> 
 
/bean> 

把所有Mybatis接口類都放置在persistence下。配置的切面類是ReadWriteInterceptor。這樣當Mapper接口的方法被調用時,會先調用這個切面類的readOrWriteDB方法。在這里需要注意aop:aspect>中的order="1" 配置,主要是為了解決切面于切面之間的優先級問題,因為整個系統中不太可能只有一個切面類。

Spring AOP 切面類實現

public class ReadWriteInterceptor { 
  private static final String DB_SERVICE = "dbService"; 
  private ListString> readMethodList = new ArrayListString>(); 
  private ListString> writeMethodList = new ArrayListString>(); 
  public Object readOrWriteDB(ProceedingJoinPoint pjp) throws Throwable { 
    String methodName = pjp.getSignature().getName(); 
    if (isChooseReadDB(methodName)) { 
      //選擇slave數據源 
    } else if (isChooseWriteDB(methodName)) { 
      //選擇master數據源 
    } else { 
     //選擇master數據源 
    } 
    return pjp.proceed(); 
} 
 
 private boolean isChooseWriteDB(String methodName) { 
   for (String mappedName : this.writeMethodList) { 
     if (isMatch(methodName, mappedName)) { 
       return true; 
     } 
   } 
  return false; 
} 
 
 private boolean isChooseReadDB(String methodName) { 
  for (String mappedName : this.readMethodList) { 
    if (isMatch(methodName, mappedName)) { 
      return true; 
    } 
  } 
  return false; 
} 
 
 private boolean isMatch(String methodName, String mappedName) { 
  return PatternMatchUtils.simpleMatch(mappedName, methodName); 
} 
 
 public ListString> getReadMethodList() { 
  return readMethodList; 
 } 
 
 public void setReadMethodList(ListString> readMethodList) { 
  this.readMethodList = readMethodList; 
} 
 
 public ListString> getWriteMethodList() { 
  return writeMethodList; 
 } 
 
 public void setWriteMethodList(ListString> writeMethodList) { 
  this.writeMethodList = writeMethodList; 
} 
 

覆蓋DynamicDataSource類中的getConnection方法

ReadWriteInterceptor中的readOrWriteDB方法只是決定選擇主還是從,我們還必須覆蓋數據源的getConnection方法,以便獲取正確的connection。一般來說,是一主多從,即一個master庫,多個slave庫的,所以還得解決多個slave庫之間負載均衡、故障轉移以及失敗重連接等問題。

1、負載均衡問題,slave不多,系統并發讀不高的話,直接使用隨機數訪問也是可以的。就是根據slave的臺數,然后產生隨機數,隨機的訪問slave。

2、故障轉移,如果發現connection獲取不到了,則把它從slave列表中移除,等其回復后,再加入到slave列表中

3、失敗重連,第一次連接失敗后,可以多嘗試幾次,如嘗試10次。

處理業務方法中的@Transactional注解

我參與的這個項目,大部分業務代碼是不需要事務的,只有極個別情況需要。那么按照上面提到的方案,如果不對業務方法中@Transactional注解進行特殊處理的話,主從的選擇會出現問題。大家都知道,如果使用了Spring的事務,那么在同一個業務方法內,只會調用一次數據源的getConnection方法,如果該業務方法內,調用的mapper接口剛好以select開頭的,就會選擇slave庫,那么接下來調用以insert開頭的mapper接口方法時,會把數據寫入到slave庫。如何解決這個問題呢?必須在進入標有@Transactional注解的業務方法前,指定選擇master主庫。可以通過覆蓋DataSourceTransactionManager類中的doBegin方法,如下:

public class MyTransactionManager extendsDataSourceTransactionManager{ 
 
@Override 
 
protected void doBegin(Object transaction, TransactionDefinitiondefinition) { 
 
//選擇master數據庫 
 
super.doBegin(transaction, definition); 
 
} 
 
} 

這樣既可以避免,把數據寫入到從庫的問題。

總結

本人的解決方案是基于項目實際的,不一定合適你,我只是展示了解決方案而已。當然你可以選擇開源的框架,像阿里的Cobar,360的Atlas。

感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

您可能感興趣的文章:
  • Spring AOP面向切面編程實現原理方法詳解
  • 解決springboot的aop切面不起作用問題(失效的排查)
  • SpringBoot整合aop面向切面編程過程解析
  • springboot配置aop切面日志打印過程解析
  • Spring 面向切面編程AOP實現詳解
  • 詳解Spring AOP 實現“切面式”valid校驗
  • 詳解spring面向切面aop攔截器
  • Spring AOP面向切面編程實現及配置詳解

標簽:樂山 內江 大連 南京 貸款邀約 廣州 黃石 銅川

巨人網絡通訊聲明:本文標題《Spring AOP切面解決數據庫讀寫分離實例詳解》,本文關鍵詞  Spring,AOP,切面,解決,數據庫,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《Spring AOP切面解決數據庫讀寫分離實例詳解》相關的同類信息!
  • 本頁收集關于Spring AOP切面解決數據庫讀寫分離實例詳解的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    亚洲欧洲日产国产综合网| 国产亚洲精品资源在线26u| 成人欧美一区二区三区白人 | 国产一区二区美女诱惑| 国产成人自拍网| 欧美三级三级三级| 九一久久久久久| 午夜精品爽啪视频| 免费在线观看视频一区| 久久先锋影音av| 精品久久久久久最新网址| 亚洲自拍与偷拍| 日韩一区二区在线观看视频播放| 色婷婷av一区二区三区大白胸| av电影在线不卡| 欧美久久久久久久久中文字幕| 日韩欧美激情在线| 亚洲人成亚洲人成在线观看图片| 亚洲精品国产精品乱码不99| 天堂蜜桃91精品| 99re热这里只有精品视频| 在线播放国产精品二区一二区四区| 欧美一区二区高清| 亚洲色图清纯唯美| 国产曰批免费观看久久久| 在线亚洲一区观看| 国产精品沙发午睡系列990531| 亚洲精品一二三四区| 韩国av一区二区三区在线观看| 色哟哟日韩精品| 国产欧美一区二区精品性| 美女任你摸久久 | 国产一区二区女| 日韩视频免费直播| 丁香婷婷综合色啪| 首页国产欧美久久| 一区二区三区高清不卡| 在线综合亚洲欧美在线视频| 国产不卡在线一区| 久久国产精品区| 欧美日韩一区二区三区四区 | 亚洲精品视频免费观看| 偷拍自拍另类欧美| 激情五月激情综合网| 91麻豆国产在线观看| 综合av第一页| 国产精品白丝jk黑袜喷水| 精品制服美女久久| 精品剧情在线观看| 中文字幕亚洲综合久久菠萝蜜| 性做久久久久久| 91在线视频18| 国产视频一区不卡| 国产精品美女久久久久aⅴ国产馆 国产精品美女久久久久av爽李琼 国产精品美女久久久久高潮 | 亚洲在线视频免费观看| 国产精品久久久爽爽爽麻豆色哟哟 | 国产一区二区三区四| 国产精品卡一卡二| 欧美女孩性生活视频| 国产在线不卡一区| 九九精品一区二区| 亚洲午夜一二三区视频| 国产精品私人自拍| 欧美日本精品一区二区三区| 亚洲妇熟xx妇色黄| 久久蜜桃一区二区| 97久久人人超碰| 日韩黄色小视频| 国产午夜精品一区二区三区嫩草| 日本高清不卡在线观看| 国产激情91久久精品导航| 蜜桃视频在线观看一区| 亚洲第一久久影院| 亚洲精品高清在线| 午夜久久电影网| 蜜臀精品一区二区三区在线观看| 日韩午夜激情免费电影| 99精品1区2区| 欧美色区777第一页| 欧美日韩中文国产| 成熟亚洲日本毛茸茸凸凹| 欧美羞羞免费网站| 99久久久久久| 国产精品一级黄| 中文字幕欧美激情| 日韩精品一区二区三区中文不卡 | 在线免费观看视频一区| 国产欧美一区二区精品秋霞影院 | 91精品国产91久久久久久一区二区| 91福利资源站| 久久久国产一区二区三区四区小说 | 国产又粗又猛又爽又黄91精品| 丝袜美腿成人在线| 国产精品三级久久久久三级| 欧美精品一级二级三级| 欧美午夜理伦三级在线观看| 美女任你摸久久| 国产在线不卡一卡二卡三卡四卡| 亚洲成a人片在线不卡一二三区| 亚洲精品国产精品乱码不99| 亚洲日本免费电影| 视频在线观看一区| 高清在线成人网| 欧美日韩国产一级片| 精品国产91乱码一区二区三区| 精品国产乱码久久久久久浪潮| 久久综合久久鬼色中文字| ...xxx性欧美| 蜜桃久久久久久| 91麻豆蜜桃一区二区三区| 久久久久久久免费视频了| 亚洲精品ww久久久久久p站| 日韩专区中文字幕一区二区| 极品少妇一区二区三区精品视频| 95精品视频在线| 欧美xxx久久| 欧美另类z0zxhd电影| 亚洲一区免费观看| 久久99日本精品| 国产欧美一区视频| 国产精品99久久久久| 欧美国产日韩亚洲一区| 成人激情校园春色| 五月激情综合网| 国产精品九色蝌蚪自拍| 毛片不卡一区二区| 91精品91久久久中77777| 欧美三日本三级三级在线播放| 欧美日韩国产一级片| 久久嫩草精品久久久久| 99视频一区二区三区| 福利电影一区二区| 日韩女优av电影在线观看| 91麻豆精品91久久久久久清纯| 91在线观看成人| 欧美性xxxxx极品少妇| 蜜臀久久99精品久久久久宅男 | 中文字幕在线一区免费| 欧美成人性福生活免费看| 成人精品免费网站| 99免费精品视频| 欧美老肥妇做.爰bbww视频| 色激情天天射综合网| 亚洲午夜一区二区| 欧美日韩综合不卡| 国产精品一区二区果冻传媒| 国产精品久久久久久久久免费樱桃| 99re这里只有精品视频首页| 国产精品久久久久影院老司| 欧美午夜精品一区二区蜜桃| 日产国产高清一区二区三区| 久久精品夜色噜噜亚洲a∨| 色综合天天综合在线视频| 亚洲国产va精品久久久不卡综合 | 国产乱码精品一区二区三区五月婷| 日韩亚洲欧美高清| 色婷婷久久综合| 国产精品一区三区| 视频一区视频二区中文| 国产区在线观看成人精品| 3atv一区二区三区| 本田岬高潮一区二区三区| 久久精品国产亚洲高清剧情介绍 | av亚洲精华国产精华精| 中文字幕一区二区视频| 久久久久久免费| 一区二区三区欧美| 性久久久久久久| 国内精品国产三级国产a久久| 老司机精品视频在线| 不卡欧美aaaaa| 欧美人伦禁忌dvd放荡欲情| 国产综合久久久久久鬼色| 欧美四级电影网| 国产高清精品网站| 久久色成人在线| 欧美体内she精高潮| 欧美精品少妇一区二区三区 | 亚洲免费av高清| 欧美一区二视频| 久久9热精品视频| 精品国产91洋老外米糕| 蜜桃一区二区三区在线| 欧美视频在线播放| heyzo一本久久综合| 精品视频在线视频| 成人app软件下载大全免费| 色综合天天综合网天天看片| 亚洲午夜精品网| 一区二区三区精品视频在线| 国产女人18毛片水真多成人如厕| 日韩欧美视频在线| 国产精品久99| 亚洲乱码中文字幕| 国产伦精一区二区三区| 欧美人妇做爰xxxⅹ性高电影| 91亚洲国产成人精品一区二区三| 欧美在线播放高清精品| 视频一区二区不卡| 不卡视频在线看|