多租户Spring Boot项目使用TransactionInterceptor时数据源不切换怎么解决?
问题根因
- 你当前实现的多租户路由逻辑仅对接Hibernate的
MultiTenantConnectionProvider,只有走JpaRepository的请求会触发租户数据源切换 - 配置中注入给
JdbcDaoSupport的jdbcTemplate是绑定了默认数据源的单例实例,没有接入多租户路由逻辑,所以相关方法永远使用默认数据源 - 即使添加了事务代理,事务管理器也只会从
jdbcTemplate绑定的固定数据源获取连接,不会触发租户切换
解决方案
1. 实现多租户感知的动态数据源
复用你现有租户上下文的逻辑,实现动态路由数据源,保证路由规则和MultiTenantConnectionProvider完全一致:
public class DynamicMultiTenantDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { // 此处返回当前请求的租户ID,和你Interceptor中存的租户标识、MultiTenantConnectionProvider的路由规则完全对齐 return TenantContextHolder.getCurrentTenantId(); } }
2. 替换原有JdbcTemplate的绑定数据源
修改Spring配置,把动态数据源注入给JdbcTemplate:
<!-- 配置动态数据源,targetDataSources和你MultiTenantConnectionProvider用的数据源池保持一致即可 --> <bean id="dynamicMultiTenantDataSource" class="你实现的DynamicMultiTenantDataSource全类名"> <property name="targetDataSources"> <map> <entry key="租户1ID" value-ref="租户1数据源Bean"/> <entry key="租户2ID" value-ref="租户2数据源Bean"/> <!-- 其余租户数据源配置 --> </map> </property> <property name="defaultTargetDataSource" ref="默认数据源Bean"/> </bean> <!-- 替换原有jdbcTemplate配置 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dynamicMultiTenantDataSource"/> </bean>
3. 验证事务一致性
你现有配置中已经统一使用同一个transactionManager,只要动态数据源的路由规则和Hibernate侧完全一致,JdbcDaoSupport的方法和JpaRepository就会在同一个事务中使用同一个租户的数据源,不会再出现数据源不切换的问题。
内容的提问来源于stack exchange,提问作者mj. rahmati
相关产品推荐
相关产品推荐

