springboot源码分析 - AbstractRoutingDataSource多数据源方案的分析
2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
????原本想用springboot+mybatis做多數(shù)據(jù)源的切換方案,想通過(guò)借鑒網(wǎng)上現(xiàn)有的方案,結(jié)果搜索后大量都是使用AbstractRoutingDataSource多數(shù)據(jù)源方案,通過(guò)實(shí)踐后,發(fā)現(xiàn)如果聲明了事務(wù),將會(huì)在事務(wù)內(nèi)部切換數(shù)據(jù)源失敗。結(jié)果,就是debug,看源碼找原因。下面是springboot+mybatis的調(diào)用棧,如果有點(diǎn)功力的同學(xué)們一看就知道了。
存在transaction情況下@Transactional切面切入攔截 DataSourceTransactionManagerdoBegin從threadlocal holder中獲取connection獲取不到獲取連接AbstractRoutingDataSource#getConnection封裝holder,存入threadLocal中,key為AbstractRoutingDataSource 獲取到,不再AbstractRoutingDataSource#getConnection此時(shí),已經(jīng)獲取到connection,如果@Transactional注解還有切換數(shù)據(jù)源的切面,則使用切面中切換好的數(shù)據(jù)源,如果沒(méi)有其他注解,則獲得配置的defaultDataSource的數(shù)據(jù)源。======================= step2 =============================== 之后,調(diào)用mybatis的mappermybatisExecutorprepareStatementgetConnection()SpringManagedTransactiongetConnection() 查看threadLocal中,key為AbstractRoutingDataSource,取出connection的holder如果有用holder里面的connection如果沒(méi)有從AbstractRoutingDataSource獲取新的連接======================= step3 ==================================== @Transactional注解的方法中還在調(diào)用其他需要切換數(shù)據(jù)源的service或者方法仍然走step2,由于從threadLocal可以獲取到connection,所以不會(huì)從AbstractRoutingDataSource獲取新的連接,也就是切換數(shù)據(jù)源失敗????這里的AbstractRoutingDataSource#getConnection方法是切換數(shù)據(jù)源的關(guān)鍵。如果在事務(wù)過(guò)程中,我們mybatis每次都是獲取threadlocal中key為AbstractRoutingDataSource的connection,則不會(huì)再調(diào)用AbstractRoutingDataSource中的getConnection方法切換數(shù)據(jù)源。
? ? 如果想解決這個(gè)問(wèn)題,自定義吧。。。
?
轉(zhuǎn)載于:https://my.oschina.net/thinwonton/blog/2962391
總結(jié)
以上是生活随笔為你收集整理的springboot源码分析 - AbstractRoutingDataSource多数据源方案的分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 在VSCode中编写Kotlin/Jav
- 下一篇: std::vector使用简介