【发布时间】:2019-08-28 14:31:11
【问题描述】:
我正在尝试使用 spring 类实现数据库读/写分离(我使用了本教程)
抽象路由数据源
我正在开发的应用程序正在使用多线程和连接池 (hikari)。所以我为每个租户创建了一个(主/副本数据源)
这就是我创建数据源的方式
公共数据源路由数据源(字符串tenantId, 字符串数据库MasterUrl, 字符串数据库ReplicaUrl, 字符串用户, 字符串密码){ final RoutingDataSource routingDataSource = new RoutingDataSource();
final DataSource masterDataSource = buildTargetDataSource(tenantId,
cachePrepStmtsValue,
prepStmtCacheSize,
prepStmtCacheSqlLimit,
databaseMasterUrl,
driverClass,
user,
password,
MASTER_DATASOURCE_PREFIX);
final DataSource replicaDataSource = buildTargetDataSource(poolName + tenantId,
cachePrepStmtsValue,
prepStmtCacheSize,
prepStmtCacheSqlLimit,
databaseReplicaUrl,
driverClass,
user,
password,
REPLICA_DATASOURCE_PREFIX);
final Map<Object, Object> targetDataSources = new HashMap<>();
targetDataSources.put(DbContext.DbType.MASTER, masterDataSource);
targetDataSources.put(DbContext.DbType.REPLICA, replicaDataSource);
routingDataSource.setTargetDataSources(targetDataSources);
routingDataSource.setDefaultTargetDataSource(masterDataSource);
routingDataSource.afterPropertiesSet();
return routingDataSource;
}
这是确定上下文的方式
public class RoutingDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DbContext.getDbType();
}
这就是我告诉事务切换上下文的方式
@Transactional(readOnly = true)
public Opportunite consulter(UUID personUuid) {
DbContext.setDbType(DbContext.DbType.REPLICA);
//some work
DbContext.reset();
return some_result ;
}
代码编译正常,但并没有真正切换上下文。事实上,调试后的问题是在设置事务之前请求了数据源。当事务最终建立时,为时已晚,数据源已经加载完毕。
如何解决此问题?谢谢。
【问题讨论】:
-
您好。您找到解决问题的方法了吗?我在同一条船上,我无法即时更改上下文。无论第一次设置的上下文是什么,这就是我所坚持的。
-
@user1830833 我已经发布了这个问题的答案
标签: spring routing transactions datasource