springboot源碼分析 - AbstractRoutingDataSource多數據源方案的分析

    本來想用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

相關文章
相關標籤/搜索