Bonjour,
Je développe une appli web avec Spring. J'utilise l'API Spring JDBC pour l'accès à la base de données. Récemment la base de données (Oracle 11g) et le serveur d'application (Tomcat) ont été migrés dans un "Datacentre" aux Etats-Unis.
Depuis des scripts Java ou des JUnit que je lance sur mon poste en France rament lors de l'accès aux données. Jusqu'ici rien de très surprenant, la latence réseau due à l'éloignement de la base en est la cause.
Cependant le comportement n'est pas celui auquel je m'attendais. Je pensais qu'une requête SELECT allait prendre plus de temps à s'exécuter mais que une fois les résultats transférés sur mon PC, le parcours du ResultSet JDBC serait aussi rapide. Or ce n'est pas ce qui se passe. Je constate qu'il y a une latence à chaque appel de rs.getString(..) pour chaque ligne et itération du ResultSet. Comme si les lignes composant le ResultSet étaient transférées une à une lors de l'itération sur le ResultSet. Or je pensais que tous les résultats étaient ramenés en masse côté appli Java puis qu'on bouclait dessus avec le ResultSet.
Quelqu'un pourrait-il me confirmer ce comportement de JDBC et m'apporter de plus amples explications ?
Si les lignes sont bien ramenées une à une, y aurait-il un moyen avec JDBC d'exécuter une requête afin que les lignes soient ramenées en masse de façon et ne pas avoir de latence à l'intérieur de l'itération sur le ResultSet ? Je sais qu'il est possible d'avoir ce genre de comportement "batch" pour les UPDATE et les INSERT où l'on envoie par exemple 2000 insert d'un coup à la base en un seul aller-retour.
Un exemple de code pour illustrer mon propos :
Donc pour reprendre, je pensais que le fait que la base de données soit très éloignées de mon PC où tourne le code allait augmenter le temps d'apparition du log "Commence à recevoir des résultats de la base de données" et c'est tout. Or il y a également de la latence sur les getters du resultSet.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 return jdbcTemplate.query("select * from produit", new ResultSetExtractor<List<Produit>>() { @Override public List<Produit> extractData(ResultSet rs) throws SQLException, DataAccessException { List<Produit> produits = new ArrayList<Produit>(); LOGGER.debug("Commence à recevoir des résultats de la base de données"); while (rs.next()) { Produit p = new Produit(); p.setId(rs.getLong("id"));// Latence à laquelle je ne m'attendais pas p.setName(rs.getString("name"));// Latence à laquelle je ne m'attendais pas ... etc. produits.add(p); } return produits; } });
Merci d'avance pour votre aide
Partager