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 :

[Derby] Un seul accès à la fois pour deux programmes ?


Sujet :

JDBC Java

  1. #1
    Membre actif
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2006
    Messages
    958
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Janvier 2006
    Messages : 958
    Points : 213
    Points
    213
    Par défaut [Derby] Un seul accès à la fois pour deux programmes ?
    bonjour

    voilà, j'adapte en ce moment un programme pour en faire un service.
    j'utilise javaexe.

    le résultat sera un programme dont 2 instances tourneront en parallèle : une gérant la partie purement "service" (elle lance 2 threads qui se répètent dans le temps), et une, "séparée", gérant l'icône de la barre des tâches.

    c'est le même programme mais dans chaque instance une partie différente sera appelée.

    mon problème est que ces deux parties font toutes deux appel à une base derby; ce que je voudrais éviter c'est un appel simultané à la base.

    comme les deux instances sont différentes, les techniques gérant le multi-thread ne marchent pas (je parle de "synchronised", ou de sémaphores).

    y-a-t'il un moyen avec derby de n'autoriser q'un accès à la fois, même par deux programmes différents?

    merci

    olivier

  2. #2
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 807
    Points
    48 807
    Par défaut
    Non, et il es déconseillé d'avoir plusieurs instance sur le même fichier derby, ce n'est pas prévu pour, tu va les corrompre.

    Si tu veux attaquer une base de données fichier sans serveur depuis plusieurs programme, je ne connais que sqlite qui en sois capable (il y a des driver java pour sqlite) mais les fichiers doivent être locaux, pas sur un montage réseau.

    Et là t'as plus la question à te poser de savoir qui attaque quand, tous peuvent y aller en même temps.

  3. #3
    Membre actif
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2006
    Messages
    958
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Janvier 2006
    Messages : 958
    Points : 213
    Points
    213
    Par défaut
    oui ça m'intéresse mais quid des problèmes d'accès concurrent, je veux dire si un utilisateur veut modifier dans un enregistrement 2 valeurs et qu'il n'en a modifié qu'une tandis qu'un autre programme lit les 2 valeurs?

  4. #4
    Membre actif
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2006
    Messages
    958
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Janvier 2006
    Messages : 958
    Points : 213
    Points
    213
    Par défaut
    ok sqlite convient bien pour ce que je veux faire.
    j'ai trouvé http://www.developpez.net/forums/d38...dacces-sqlite/ qui répond à ma question.

    merci

  5. #5
    Membre actif
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2006
    Messages
    958
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Janvier 2006
    Messages : 958
    Points : 213
    Points
    213

  6. #6
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 807
    Points
    48 807
    Par défaut
    Citation Envoyé par olivier57b Voir le message
    oui ça m'intéresse mais quid des problèmes d'accès concurrent, je veux dire si un utilisateur veut modifier dans un enregistrement 2 valeurs et qu'il n'en a modifié qu'une tandis qu'un autre programme lit les 2 valeurs?
    C'est pour ça qu'en SQL un utilise des transactions

  7. #7
    Membre actif
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2006
    Messages
    958
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Janvier 2006
    Messages : 958
    Points : 213
    Points
    213
    Par défaut
    j'ai une question encore; si un programme débute une transaction et que pendant celle-ci un autre programme veut en débuter une, comment réagit le système?

    exception?mise en attente?

  8. #8
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 807
    Points
    48 807
    Par défaut
    Gestion parallèles des transactions si c'est possible (deux transactions qui travaillent sur des lignes différentes d'une tables peuvent très bien rouler en parallèle)

  9. #9
    Membre actif
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2006
    Messages
    958
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Janvier 2006
    Messages : 958
    Points : 213
    Points
    213
    Par défaut
    bon je m'explique : je voudrais justement éviter la gestion parallèle.je voudrais marquer un bloc de code comme une unique transaction, bien que il n'y ait pas que des instructions JDBC dedans, mais aussi du code java SE.

    ceci afin d'éviter d'avoir un "select" juste à moitié.

    j'ai vui que je pouvais utiliser "connexion.setAutoCommit=false;" suivi d'un commit mais l'exemple que j'ai testé me laisse dubitatif; il s'agissait de ceci:

    un lanceur (avec une méthode main) démarre 2 threads simultanément.le 1er thread modifie une base sqlite mais de manière partielle; il attend 5 secondes (avec un thread.sleep) puis il fait la deuxième modification, qui complète la première.
    le deuxième thread utilise sa propre connexion, et lit dans la base et affiche le résultat.

    Cet exemple "marche" : j'ai bien une base à moitié modifiée lue par le 2e thread.

    ensuite je modifie mon 1er thread pour utiliser une transaction : avant la modification de la base, je débute une transaction, que je committe après le deuxième changement.
    et là tout se passe comme si le thread.sleep avait disparu : le résultat du 2e thread est juste du premier coup! il aurait dû soit lancer une exception, soit attendre.
    j'aimerais comprendre pourquoi.

    voici mes codes :

    lanceur:
    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
    package acces_concurrents;
     
    public class Deux_acces_qui_se_genent {
     
        /**
         * @param args
         */
        public static void main(String[] args) {
     
            Gene_1 gene_1 = new Gene_1();
            Gene_2 gene_2 = new Gene_2();
     
            gene_1.start();
     
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
     
            gene_2.start();
        }
     
    }
    gene_1
    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
    package acces_concurrents;
     
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.sql.Statement;
     
    /**
     * <p>se connecte à sqlite et écrit un nombre et son carré comme unique enregistrement 
     * de la base "nombres"</p>
     * @author lolveley
     *
     */
    public class Gene_1 extends Thread {
     
        @Override
        public void run() {
     
            Statement stmt = null;
            Connection con = null;
     
            try {
                // sqlite driver
                Class.forName("org.sqlite.JDBC");
                con = DriverManager.getConnection("jdbc:sqlite:genants.db");
                con.setAutoCommit(false);
                stmt = con.createStatement();
                stmt.execute("drop table if exists GENANTS;");
                stmt.execute("create table GENANTS (n int,n2 int);");
                stmt.executeUpdate("insert into GENANTS values (1,1);");
                stmt.executeUpdate("update GENANTS set n=2 where n=1;");
     
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
     
                stmt.executeUpdate("update GENANTS set n2=2 where n=2;");
                con.commit();
     
            } catch (ClassNotFoundException | SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
     
            try {
                con.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
     
        }
    gene_2
    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
    package acces_concurrents;
     
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
     
    /**
     * <p>Se connecte à sqlite et lit l'enregistrement (n,n^2) et l'affiche</p>
     * @author lolveley
     *
     */
    public class Gene_2 extends Thread {
     
        @Override
        public void run() {
     
            Statement stmt = null;
            Connection con = null;
            ResultSet rs = null;
            try {
                // sqlite driver
                Class.forName("org.sqlite.JDBC");
                con = DriverManager.getConnection("jdbc:sqlite:genants.db");
                stmt = con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
                rs = stmt.executeQuery("select * from GENANTS;");
     
                int a = rs.getInt("n");
                int a2 = rs.getInt("n2");
                rs.close();
                System.out.println("n=" + a + " / n²=" + a2);
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
     
                rs = stmt.executeQuery("select * from GENANTS;");
                rs.next();
                a = a2 = 0;
                a = rs.getInt("n");
                a2 = rs.getInt("n2");
                rs.close();
                System.out.println("n=" + a + " / n²=" + a2);
     
            } catch (ClassNotFoundException | SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
     
        }
    }
    merci

  10. #10
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 807
    Points
    48 807
    Par défaut
    drop et create sont des instruction DDL, ça arrête normalement automatiquement les transactions qui les entoure. En pratique, je ne sais pas comment ça se passage avec sqlite et ses verrous.

    Tu devrais donc bien penser à faire un begin après tron create table pour être sur d'avoir bien démarré une transaction.

    Ensuite, il y a plusieurs niveua d'isolation entre les transaction, suivant que tu veuille autoriser le read un commited, les phantom read, etc. La plus strict isolation c'est le niveau serializable.

    Enfin, comme le thread 2 ne vois pas ta transaction, il est tout à fait possible qu'il continue à travailler sur les données d'origine, avant le démarrage de thread 1, ce qui est correct d'un point de vue transactionnel, les données sont cohérentes. Tant qu'il ne fait que des selects, il est plus facile, d'un point de vue performances, de le laisser accéder aux ancienne données. Evidement, ça posera un problème si lui aussi essaie de modifier une ligne dans la table, ce ne sera pas possible en respectant la transaction. Tout dépend des stratégie de verrouialge de sqlite.

Discussions similaires

  1. Réponses: 3
    Dernier message: 22/06/2015, 07h34
  2. Mutex pour deux programmes
    Par LuckyLuke56 dans le forum Outils
    Réponses: 2
    Dernier message: 15/02/2013, 19h23
  3. une seule source pour deux programmes
    Par micoudev dans le forum Langage
    Réponses: 5
    Dernier message: 02/02/2012, 20h12
  4. Limiter l'accès à 1 seul utilisateur à la fois
    Par RoyBatty dans le forum Langage
    Réponses: 11
    Dernier message: 19/03/2007, 21h28
  5. Réponses: 7
    Dernier message: 01/02/2006, 15h49

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