亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JSP > 正文

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

2024-09-05 00:23:05
字體:
來源:轉載
供稿:網友

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,切面,數據庫,讀寫分離,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 List<String> readMethodList = new ArrayList<String>();   private List<String> writeMethodList = new ArrayList<String>(); 
  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 List<String> getReadMethodList() {   return readMethodList;  }   public void setReadMethodList(List<String> readMethodList) {   this.readMethodList = readMethodList; }   public List<String> getWriteMethodList() {   return writeMethodList;  }   public void setWriteMethodList(List<String> 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。

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


注:相關教程知識閱讀請移步到JSP教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
全球成人中文在线| 国产精品偷伦视频免费观看国产| 日韩精品中文字幕视频在线| 亚洲a级在线观看| 91成人免费观看网站| 欧美日韩国产色| 欧美激情亚洲另类| 日韩av一区在线观看| 日韩二区三区在线| 欧美色另类天堂2015| 欧日韩在线观看| 日韩av日韩在线观看| 在线成人一区二区| 91精品一区二区| 九九热精品在线| 91免费观看网站| 97激碰免费视频| 中文字幕日韩免费视频| www.美女亚洲精品| 国内精品小视频| 欧美一级电影免费在线观看| 欧美日本中文字幕| 日韩在线视频观看| 亚洲人成网站999久久久综合| 国产精品99久久久久久www| 亚洲欧美另类自拍| 91在线精品视频| 欧美性生交xxxxxdddd| 亚洲欧美中文日韩v在线观看| 欧美一级淫片videoshd| 国产欧美日韩视频| 欧美伊久线香蕉线新在线| 午夜免费日韩视频| 最近2019中文字幕在线高清| 91禁外国网站| 影音先锋欧美在线资源| 国产成人激情小视频| 91麻豆桃色免费看| 日韩精品福利网站| 国产欧美日韩中文| 91在线精品播放| 久久99国产综合精品女同| 日韩精品有码在线观看| 色爱精品视频一区| 亚洲国产另类久久精品| 欧美成人精品影院| 91人人爽人人爽人人精88v| 中文字幕九色91在线| 国产在线播放不卡| 亚洲香蕉伊综合在人在线视看| xx视频.9999.com| 亚洲欧美一区二区激情| 91免费综合在线| 久久久在线免费观看| 精品久久香蕉国产线看观看亚洲| 少妇久久久久久| 中文字幕免费精品一区高清| 精品视频www| 欧美不卡视频一区发布| 久久精品国亚洲| 亚洲欧美日韩国产成人| 久久韩剧网电视剧| 欧洲永久精品大片ww免费漫画| 26uuu日韩精品一区二区| 51视频国产精品一区二区| 亚洲国产又黄又爽女人高潮的| 2019中文字幕在线观看| 亚洲国产一区二区三区在线观看| 精品国产区一区二区三区在线观看| 九九热这里只有精品免费看| 久久久人成影片一区二区三区| 欧美日韩成人黄色| 国产在线精品自拍| 精品夜色国产国偷在线| 欧美日韩裸体免费视频| 亚洲视频777| 亚洲午夜激情免费视频| 欧美一级在线亚洲天堂| 成人性教育视频在线观看| 日韩精品黄色网| 91久久久亚洲精品| 欧美特级www| 午夜剧场成人观在线视频免费观看| 91成人在线播放| 欧美激情一区二区三级高清视频| 成人高清视频观看www| 欧美视频免费在线| 成人看片人aa| 久久精品国产亚洲7777| 精品国偷自产在线视频99| 欧美精品久久久久久久| 国产精品久久久久7777婷婷| 91久久国产综合久久91精品网站| 成人激情免费在线| 色婷婷av一区二区三区在线观看| 欧美成人亚洲成人日韩成人| 2019亚洲日韩新视频| 91精品视频在线免费观看| 亚洲另类激情图| 国产一区二区三区久久精品| 日韩免费在线免费观看| 久久影视电视剧凤归四时歌| 国产亚洲人成网站在线观看| 91免费福利视频| 午夜精品一区二区三区视频免费看| 欧美激情第99页| 亚洲天堂久久av| 51久久精品夜色国产麻豆| 在线丨暗呦小u女国产精品| 日韩在线免费av| 欧美大尺度在线观看| 在线看日韩欧美| 91网在线免费观看| 国产日韩在线亚洲字幕中文| 欧美极品欧美精品欧美视频| 国产精品入口尤物| 色爱av美腿丝袜综合粉嫩av| 精品视频久久久久久| 久久精品一区中文字幕| 色偷偷av一区二区三区乱| 岛国av一区二区三区| 中文字幕精品—区二区| 欧美黑人视频一区| 国产精品精品一区二区三区午夜版| 亚洲天堂av在线免费观看| 欧美日韩在线视频观看| 亚洲精品乱码久久久久久按摩观| 国产成人精品亚洲精品| 久久精品男人天堂| 国产精品自拍偷拍| 亚洲欧洲在线免费| 国产成人亚洲综合青青| 91九色单男在线观看| 亚洲影视九九影院在线观看| 国产精品444| www.美女亚洲精品| 亚洲视频在线观看视频| 亚洲美女视频网站| 久久久久久com| 日韩成人av在线播放| 久久99精品视频一区97| 国产精品香蕉av| 亚洲精品视频网上网址在线观看| 国产狼人综合免费视频| 97视频在线观看网址| 成人伊人精品色xxxx视频| 亚洲黄页视频免费观看| 欧美大胆在线视频| 欧美丰满老妇厨房牲生活| 欧美高清性猛交| 亚洲国产高清高潮精品美女| 国产欧美日韩精品专区| 日韩电影免费在线观看| 日韩av三级在线观看| 福利一区福利二区微拍刺激| 国产成人avxxxxx在线看| 亚洲男人天堂2024| 成人在线国产精品| 国内精品模特av私拍在线观看| 日韩精品在线观看网站| 国产视频丨精品|在线观看| 精品久久久av| 久久久91精品国产一区不卡| 日韩久久精品电影|