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 :
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.
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; } }
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:
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!
Partager