本來想用springboot+mybatis作多數據源的切換方案,想經過借鑑網上現有的方案,結果搜索後大量都是使用AbstractRoutingDataSource多數據源方案,經過實踐後,發現若是聲明瞭事務,將會在事務內部切換數據源失敗。結果,就是debug,看源碼找緣由。下面是springboot+mybatis的調用棧,若是有點功力的同窗們一看就知道了。spring
存在transaction狀況下 @Transactional切面切入攔截 DataSourceTransactionManager doBegin 從threadlocal holder中獲取connection 獲取不到 獲取鏈接 AbstractRoutingDataSource#getConnection 封裝holder,存入threadLocal中,key爲AbstractRoutingDataSource 獲取到,再也不AbstractRoutingDataSource#getConnection 此時,已經獲取到connection,若是@Transactional註解還有切換數據源的切面,則使用切面中切換好的數據源,若是沒有其餘註解,則得到配置的defaultDataSource的數據源。 ======================= step2 =============================== 以後,調用mybatis的mapper mybatis Executor prepareStatement getConnection() SpringManagedTransaction getConnection() 查看threadLocal中,key爲AbstractRoutingDataSource,取出connection的holder 若是有用holder裏面的connection 若是沒有從AbstractRoutingDataSource獲取新的鏈接 ======================= step3 ==================================== @Transactional註解的方法中還在調用其餘須要切換數據源的service或者方法 仍然走step2,因爲從threadLocal能夠獲取到connection,因此不會從AbstractRoutingDataSource獲取新的鏈接,也就是切換數據源失敗
這裏的AbstractRoutingDataSource#getConnection方法是切換數據源的關鍵。若是在事務過程當中,咱們mybatis每次都是獲取threadlocal中key爲AbstractRoutingDataSource的connection,則不會再調用AbstractRoutingDataSource中的getConnection方法切換數據源。springboot
若是想解決這個問題,自定義吧。。。mybatis