基於spring多資料來源動態呼叫及其事務處理

2021-08-03 03:45:24 字數 4666 閱讀 3624

有些時候,我們需要連線多個資料庫,但是,在方法呼叫前並不知道到底是呼叫哪個。即同時保持多個資料庫的連線,在方法中根據傳入的引數來確定。

下圖的單資料來源的呼叫和多資料來源動態呼叫的流程,可以看出在dao層中需要有乙個datasource選擇器,來確定到底是呼叫哪個資料來源。

對dao層提供乙個公共父類,保持有多個資料來源的連線(本人是基於ibatis,即保持多個sqlsessiontemplate)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

/**

* created by hzlizhou on 2017/2/6.

*/

publicabstractclassmultidatasourcedaoimplementsidaosupport

publicmapgetsqlsessiontemplatemap()

publicvoidsetsqlsessiontemplatemap(mapsqlsessiontemplatemap)

//子類通過這個方法動態獲取sqlsessiontemplate

protectedsqlsessiontemplate getsqlsessiontemplate()

}

multidatasourceselector是乙個藉口,根據當前的呼叫環境,返回不不同的引數,根據這個引數就可以確定使用哪乙個sqlsessiontemplate,例如我是把當前環境放入到threadlocal中的

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

publicinte***cemultidatasourceselector

publicclassdubbocontextdatasourceselectorimplementsmultidatasourceselector

@override

publicstring getname()

returnres;

}

publicstring getdefaultname()

}

然後在dao層的中獲取sqlsessiontemplate的時候就是動態了。

其實這個都好辦,然後我們就面臨乙個稍微複雜一點的問題,那datasource是動態的,事務也就必須是動態了的。而且還對原有的**沒有侵入(例如spring中的@transactional 註解),那實現乙個類似@transactional的方法吧。名字就叫做@dynamictransactional

1

2

3

4

5

6

7

8

9

@documented

@target()

@retention(runtime)

public@inte***cedynamictransactional ;

}

基本思想是在通過aop切面攔截@dynamictransactional註解,呼叫,然後自己程式設計實現事務

切面內的核心方法是

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

privateobject invokewithintransaction(finalproceedingjoinpoint pjp,finaldynamictransactional dynamictransaction)catch(throwable throwable)

}

}

returnresult;

}

});

}

其中multitransactionmanagerholder和上面動態資料來源選擇的原理一樣,通過從threadlocal中拿去變數,選擇對應的transactionmanager返回

切面的配置:重點是怎麼對指定註解進行切面

arg-names="dynamictransaction"

pointcut="@annotation(dynamictransaction)"/>

當然,這裡只是實現了在方法上的@dynamictransactional使用,如果該註解還要對類使用,對所有函式加乙個切點,判斷該切點的類上是否有@dynamictransactional註解

注意:由於切面的優先順序,如果要實現 方法上的註解優先順序高於類上的,還需要一點點小的處理 

自己實現基於abstractroutingdatasource,把多個datasource加入到sqlsessionfactory,和之前的方式一樣,通過threadlocal來確定使用哪個datasource。

關於動態事務,上面是使用切面,自定義標籤,使用transactiontemplate來實現的,如果想更優雅的話,可以仿照datasourcetransactionmanager寫乙個

spring 多資料來源

之前嘗試的乙個多資料來源切換的功能測試可以實現了,下面進行一下簡單的筆記 testservice 方法通過以下方式進行主動切換 dynamicdatasource 類 package com.utils import org.springframework.jdbc.datasource.looku...

spring多資料來源配置

前段時間由於公司專案需求,需要多資料來源的支援,苦b折騰了兩天程式猿,話不多說,直接擼碼。classpath jdbc.properties select 1 true select 1 true org.hibernate.dialect.mysqldialect false update tru...

spring 多資料來源配置

以下是我的xml配置,在配置的過程中涉及到不同的包分配不同的資料來源,在這裡用逗號分割就好 當然萬用字元能結局的那是最好了.xmlns xsi xmlns aop xmlns tx xmlns task xmlns context xmlns rabbit xsi schemalocation sp...