Spring has dynamic datasource routing if that's where you are headed. In my case it is the same schema (WR/RO)
public class RoutingDataSource extends AbstractRoutingDataSource {
@Autowired
private DataSourceConfig dataSourceConfig;
@Override
protected Object determineCurrentLookupKey() {
return DbContextHolder.getDbType();
}
public enum DbType {
MASTER, WRITE, READONLY,
}
Then you need a custom annotation and an aspect
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ReadOnlyConnection {
}
@Aspect
@Component
@Order(1)
public class ReadOnlyConnectionInterceptor {
Pointcut(value = "execution(public * *(..))")
public void anyPublicMethod() {}
@Around("@annotation(readOnlyConnection)")
public Object proceed(ProceedingJoinPoint proceedingJoinPoint, ReadOnlyConnection readOnlyConnection) throws Throwable {
Object result = null;
try {
DbContextHolder.setDbType(DbType.READONLY);
result = proceedingJoinPoint.proceed();
DbContextHolder.clearDbType();
return result;
} finally {
DbContextHolder.clearDbType();
}
}
}
And then you can act on you DB with the tag @ReadOnlyConnection
@Override
@Transactional(readOnly = true)
@ReadOnlyConnection
public UnitDTO getUnitById(Long id) {
return unitRepository.findOne(id);
}
An example can be found here: https://github.com/afedulov/routing-data-source.
I used that as a basis for my work although it is still in progress because I still need to resolve runtime dependencies ( i.e. hibernate sharding ).
EntityManagerto get the connection parameters and using a@PostConstructannotation to create the second datasource. The only problem with this approach is that I need to restart the application if the parameters are not correct.