I have configured multiple database following this link https://fable.sh/blog/splitting-read-and-write-operations-in-spring-boot/. DB call is routed based on the Transactional annotation value. Call to DB is happening correctly till we try to make a nested call.
In my service class, I have 2 methods. One is performing read operation using Replica Server and another is performing write operation using Primary Server. But when I try to call read method inside write method, both DB calls routed through Primary server only. Below is code snippet for Service class
@Service
public class MyService {
@Autowired
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
@Transactional(readOnly = true) //Make a call to Replica Server
public List<String> replica() {
String sqlQuery = "SELECT QUERY";
return namedParameterJdbcTemplate.query(sqlQuery, (rs, rowNum) -> rs.getString(1));
}
@Transactional(readOnly = false) //Make a call to Primary Server
public List<String> primary() {
String sqlQuery = "INSERT QUERY";
namedParameterJdbcTemplate.update(sqlQuery, params);
return replica(); //DB call should be made to Replica Server but it's calling Primary Server
}
}
Below is AOP configured to route DB calls to different server based on Transactional annotation
@Aspect
@Component
@Order(0)
@Slf4j
public class DataSourceRouteInterceptor {
@Around("@annotation(org.springframework.transaction.annotation.Transactional)")
public Object proceed(ProceedingJoinPoint call) throws Throwable {
MethodSignature signature = (MethodSignature) call.getSignature();
Method method = signature.getMethod();
Transactional tx = method.getAnnotation(Transactional.class);
try {
if (tx.readOnly()) {
RoutingDataSource.setReplicaRoute();
log.info("Routing DB call to Replica Server");
}
return call.proceed();
} finally {
RoutingDataSource.clearReplicaRoute();
}
}
}
My expectation is when I call replica method inside primary method, DB calls should be routed based on the Transactional annotation value configured on that method.