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

    原本想用springboot+mybatis做多數據源的切換方案,想通過借鑑網上現有的方案,結果搜索後大量都是使用AbstractRoutingDataSource多數據源方案,通過實踐後,發現如果聲明瞭事務,將會在事務內部切換數據源失敗。結果,就是debug,看源碼找原因。下面是springboot+mybatis的調用棧,如果有點功力的同學們一看就知道了。

存在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方法切換數據源。

    如果想解決這個問題,自定義吧。。。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章