IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JDBC Java Discussion :

Connexion concurrente à une base de donnée.


Sujet :

JDBC Java

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2016
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2016
    Messages : 7
    Points : 10
    Points
    10
    Par défaut Connexion concurrente à une base de donnée.
    Bonjour à tous!
    Je suis en train de développer un serveur où plusieurs clients peuvent se connecter dessus. Ces clients lancent des requêtes au serveur qui ensuite les traitent (logique pour l'instant lol). La plupart de ces requêtes demande un accès à une base donnée et à une modification de cette dernière. Pour éviter le trop plein de connexion j'utilise la méthode du singleton comme ceci :
    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    public class SQLConnectionSingleton {
     
    	// Constant.
     
    	private volatile static SQLConnectionSingleton SINGLE;
     
    	// Variables.
     
    	private Connection connection = null;
     
    	// Constructors.
     
    	private SQLConnectionSingleton() {
    		try {
    			this.connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/auto_eval", "BD",
    					"PASSWORD");
    			this.connection.setAutoCommit(false);
    		} catch (SQLException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
     
    	// Public methods.
     
    	public static SQLConnectionSingleton getInstance() {
    		if (SINGLE == null) {
    			synchronized (SQLConnectionSingleton.class) {
    				if (SINGLE == null) {
    					SINGLE = new SQLConnectionSingleton();
    				}
    			}
    		}
    		return SINGLE;
    	}
     
    	public static void commit() {
    		if (SINGLE != null) {
    			try {
    				SINGLE.connection.commit();
    			} catch (SQLException e) {
    				ManagerError.writeError(e);
    			}
    		}
    	}
     
    	public static void rollback() {
    		if (SINGLE != null) {
    			try {
    				SINGLE.connection.rollback();
    			} catch (SQLException e) {
    				ManagerError.writeError(e);
    			}
    		}
    	}
     
    	// Getters.
     
    	public Connection getConnection() {
    		return this.connection;
    	}
    }
    Comme vous pouvez le voir, j'ai créé deux méthodes commit() et rollback() pour permettre les transactions car en effet certaines requêtes serveur, pour être réussies, doivent exécuter plusieurs requêtes SQL qui doivent elles-même être réussies. Si une requête SQL échoue je lance un rollback et si toutes les requêtes SQL réussissent je fini par un commit, et c'est de la que vient mon problème.
    Mon serveur à chaque connexion crée une thread qui s'occupera de recevoir les requêtes du client, quand un client envoie une requête, c'est cette même thread qui va gérer la requête et donc accéder à la BD via la l'unique connexion à la BD. Il faut maintenant imaginer que deux clients sont simultanément en train d'envoyer des requêtes, pour l'utilisation de la connexion à la BD il n'y a normalement pas de problème car le singleton est "volatile". Cependant si une des deux thread lance un commit lorsque l'autre thread est en milieu de transaction, cela va "commiter" la partie de la transaction effectuée par cette dernière thread.
    Je voudrai donc pouvoir éviter cela et que les deux thread puissent utiliser la connexion à la BD en concurrence et que lorsqu'une thread lance un commit cela commit seulement sa transaction et non pas celle des autres.
    Voici un petit schéma:
    Nom : Shcéma pb concurence BD.png
Affichages : 281
Taille : 27,9 Ko

    Je vous remercie d'avoir pris le temps de lire mon poste, en espérant que vous pourrez m'éclairer un peu plus sur le sujet!
    Merci, au revoir!
    Images attachées Images attachées  

  2. #2
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 274
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 274
    Points : 4 141
    Points
    4 141
    Par défaut
    C'est une mauvaise idée d'avoir une seule connection partagée.
    Sur un serveur on utilise généralement un pool de connexions, qui évite le coût de création, et chaque client pour une opération, qui peut correspondre à plusieurs requêtes, utilise une connexion issue de ce pool. Ca devrait corriger ton problème de concurrence.
    Soit tu utilises pool connu Hikari cp, Bone cp, c3p0, soit tu crées une méthode qui te renvoie une nouvelle connexion pour tester dans un premier temps.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2016
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2016
    Messages : 7
    Points : 10
    Points
    10
    Par défaut
    Bonjour, merci de votre réponse!
    Cependant je ne comprends pas pourquoi alors souvent je vois lorsqu'on parle de connexion à une base de donnée qu'il y ai souvent le singleton qui revienne en boucle.
    Et une autre question, si justement j'utilise un pool de connexion, dois-je créer autant d'utilisateurs dans la base de donnée que de connexion où je peux me connecter sur le même utilisateur?

  4. #4
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 274
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 274
    Points : 4 141
    Points
    4 141
    Par défaut
    Tu peux te contenter d'un user avec uniquement les droits nécessaires, c'est souvent ce que l'on fait.

    L'objet qui gère ta connexion peut être un singleton pour un accès facile, mais pas la connexion qu'il contient.

  5. #5
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2016
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2016
    Messages : 7
    Points : 10
    Points
    10
    Par défaut
    Très bien merci beaucoup!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Connexion sur une base de données Postgre
    Par ktox dans le forum C++Builder
    Réponses: 3
    Dernier message: 04/08/2005, 10h58
  2. connexion a plusieurs bases de données oracle
    Par tarik75 dans le forum JDBC
    Réponses: 1
    Dernier message: 06/07/2005, 13h33
  3. [DataBase]Connexion a une base de données.
    Par GETah dans le forum JDBC
    Réponses: 3
    Dernier message: 19/04/2005, 17h47
  4. connexion a une base de donné mysql
    Par ithery75 dans le forum Bases de données
    Réponses: 3
    Dernier message: 04/02/2005, 20h57
  5. connexion a une base de donnée distante mysql(site internet)
    Par rollernox dans le forum Bases de données
    Réponses: 2
    Dernier message: 06/07/2004, 13h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo