有些時候,我們需要連線多個資料庫,但是,在方法呼叫前並不知道到底是呼叫哪個。即同時保持多個資料庫的連線,在方法中根據傳入的引數來確定。
下圖的單資料來源的呼叫和多資料來源動態呼叫的流程,可以看出在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.
*/
public
abstract
class
multidatasourcedao
implements
idaosupport
public
mapgetsqlsessiontemplatemap()
public
void
setsqlsessiontemplatemap(mapsqlsessiontemplatemap)
//子類通過這個方法動態獲取sqlsessiontemplate
protected
sqlsessiontemplate 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
public
inte***ce
multidatasourceselector
public
class
dubbocontextdatasourceselector
implements
multidatasourceselector
@override
public
string getname()
return
res;
}
public
string getdefaultname()
}
然後在dao層的中獲取sqlsessiontemplate的時候就是動態了。
其實這個都好辦,然後我們就面臨乙個稍微複雜一點的問題,那datasource是動態的,事務也就必須是動態了的。而且還對原有的**沒有侵入(例如spring中的@transactional 註解),那實現乙個類似@transactional的方法吧。名字就叫做@dynamictransactional
1
2
3
4
5
6
7
8
9
@documented
@target
()
@retention
(runtime)
public
@inte***ce
dynamictransactional ;
}
基本思想是在通過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
private
object invokewithintransaction(
final
proceedingjoinpoint pjp,
final
dynamictransactional dynamictransaction)
catch
(throwable throwable)
}
}
return
result;
}
});
}
其中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...