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

Spring Web Java Discussion :

Comment ajouter un lock sur une table iBatis


Sujet :

Spring Web Java

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2006
    Messages : 48
    Points : 48
    Points
    48
    Par défaut Comment ajouter un lock sur une table iBatis
    Bonjour,

    Je voudrais mettre un lock sur une table durant la transaction. C-à-d très exactement faire une "LOCK TABLE personne WRITE;"

    Comme on peut le lire dans le code ci-dessous, je n'accepte de faire un "update" que si la valeur du champ [VERSION] est identique à la valeur que j'ai lu avant de faire la mise à jour.

    Extrait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
        //modifier une personne
        protected void updatePersonne(Personne personne) {
            [...]
            //modification
            int n = getSqlMapClientTemplate().update("Personne.updateOne", personne);
     
            if (n==0) throw new DaoException("La personne d'Id ["+personne.getId()+" n'existe pas ou bien a été modifié", 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
     
    [...]
    <sqlMap>
    [...]
        <!-- mettre à jour une personne -->
        <update id="Personne.updateOne" parameterClass="Personne.classe">
            UPDATE
            PERSONNES
            SET
            VERSION=#version#+1,
            NOM=#nom#,
            PRENOM=#prenom#,
            DATENAISSANCE=#dateNaissance#,
            MARIE=#marie#,
            NBENFANTS=#nbEnfants#
            WHERE ID=#id#
              AND VERSION=#version#
        </update>
    [...]
    </sqlMap>
    Ce que je veux faire, c'est "locker" la table personne avant ma transaction pour m'assurer que personne ne pourra modifier la valeur du champ [VERSION] durant ma transaction et enfin à la fin de la transaction libérer le verrou par un "UNLOCK TABLES".

    Comment puis-je faire cela?

    table [personne]
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    ID	VERSION	NOM	PRENOM	DATENAISSANCE	MARIE	NBENFANTS
    424	3	DUPONT	Alain	1975-11-03	0	2
    443	1	DURANT	Nathalie1984-12-07	0	2
    445	2	DUVAL	Giuseppe1991-02-05	1	0
    CODE SOURCE COMPLET:
    Classe personne:
    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
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
     
    package istia.st.springmvc.personnes.entites;
     
    import java.text.SimpleDateFormat;
    import java.util.Date;
     
    public class Personne 
    {
        //identifiant unique de la personne
        private int id;
     
        //la version actuelle
        private long version;
     
        //le nom
        private String nom;
     
        //le prénom
        private String prenom;
     
        //la date de naissance
        private Date dateNaissance;
     
        //l'état marital
        private boolean marie = false;
     
        //le nombre d'enfants
        private int nbEnfants;
     
        public int getId() {
            return id;
        }
     
        public void setId(int id) {
            this.id = id;
        }
     
        public long getVersion() {
            return version;
        }
     
        public void setVersion(long version) {
            this.version = version;
        }
     
        public String getNom() {
            return nom;
        }
     
        public void setNom(String nom) {
            this.nom = nom;
        }
     
        public String getPrenom() {
            return prenom;
        }
     
        public void setPrenom(String prenom) {
            this.prenom = prenom;
        }
     
        public Date getDateNaissance() {
            return dateNaissance;
        }
     
        public void setDateNaissance(Date dateNaissance) {
            this.dateNaissance = dateNaissance;
        }
     
        public boolean isMarie() {
            return marie;
        }
     
        public void setMarie(boolean marie) {
            this.marie = marie;
        }
     
        public int getNbEnfants() {
            return nbEnfants;
        }
     
        public void setNbEnfants(int nbEnfants) {
            this.nbEnfants = nbEnfants;
        }
     
        //constructeur par défaut
        public Personne() {
        }
     
        //constructeur avec initialisation des champs de la personne
        public Personne(int id, String nom, String prenom, Date dateNaissance, int nbEnfants, boolean marie) {
            this.id = id;
            this.marie = marie;
            this.nom = nom;
            this.prenom = prenom;
            this.dateNaissance = dateNaissance;
            this.nbEnfants = nbEnfants;
        }
     
        public Personne(int id, String nom, String prenom, Date dateNaissance, boolean marie, int nbEnfants ) {
            this.id = id;
            this.marie = marie;
            this.nom = nom;
            this.prenom = prenom;
            this.dateNaissance = dateNaissance;
            this.nbEnfants = nbEnfants;
        }
     
        //constructeur d'une perosnne par recopie d'une autre personne
        public Personne(Personne p)
        {
            setId(p.getId());
            setVersion(p.getVersion());
            setNom(p.getNom());
            setPrenom(p.getPrenom());
            setDateNaissance(p.getDateNaissance());
            setMarie(p.isMarie());
            setNbEnfants(p.getNbEnfants());
        }
     
        //toString
        public String toString() 
        {
            return "[" +
                   id + ", " +
                   version + ", " +
                   prenom + ", " +
                   nom + ", " +
                   new SimpleDateFormat("dd/MM/yyyy").format(dateNaissance) + ", " +
                   marie + ", " +
                   nbEnfants +
                   "]"; 
        }
     
     
    }
    Pour accèder à la table, les classes et interfaces:
    IDAO interface:
    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
     
    package istia.st.springmvc.personnes.dao;
     
    import istia.st.springmvc.personnes.entites.Personne;
     
    import java.util.Collection;
     
    public interface IDao 
    {
        //liste de toutes les personnes
        Collection getAll();
     
        //obtenir une personne particulière
        Personne getOne(int id);
     
        //ajouter/modifier une personne
        void saveOne(Personne personne);
     
        //supprimer une personne
        void deleteOne(int id);
    }
    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
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
     
    package istia.st.springmvc.personnes.dao;
     
    import istia.st.springmvc.personnes.entites.Personne;
    import java.util.ArrayList;
    import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;
     
    import java.util.Collection;
    import java.util.List;
     
    public class DaoImplCommon extends SqlMapClientDaoSupport implements IDao
    {
     
        //liste des personnes
        @Override
        public Collection getAll() {
            return getSqlMapClientTemplate().queryForList("Personne.getAll", null);
        }
     
        //obtenir une personne en particulier
        @Override
        public Personne getOne(int id) {
            Personne personne;
            // on la récupère dans le BD        
            List tmpP = (List) getSqlMapClientTemplate().queryForList("Personne.getOne", new Integer(id));
     
            if (tmpP.isEmpty())
                personne=null;
            else
            {
                personne = (Personne) tmpP.get(0);
            }
     
            //Personne personne = (Personne) getSqlMapClientTemplate().queryForList("Personne.getOne", new Integer(id));
            // a-t-on récupéré qq chose?
            if (personne==null)
            {
                //on lance une exception 
                throw new DaoException("La personne d'id [" + id + "] n'existe pas", 2);
            }
     
            return personne;
        }
     
        @Override
        public void saveOne(Personne personne) {
            // le paramètre personne est-il valide ?
            check(personne);
     
            //ajout ou modification ?
            if (personne.getId()==-1)
                insertPersonne(personne);
            else updatePersonne(personne);
     
            //on attend 5 sec - pour les tests mettre true au lieu de false
            System.out.println("attend 5 sec...");
            if (true) wait(5000);        
        }
     
        //suppression d'une personne
        @Override
        public void deleteOne(int id) {
            //on supprime la personne
            int n = getSqlMapClientTemplate().delete("Personne.deleteOne", new Integer(id));
     
            // a-t-on réussi
            if (n==0)
                throw new DaoException("Personne d'id ["+id+"] inconnue", 2);
        }
     
        //ajouter une personne
        protected void insertPersonne(Personne personne) {
            //1ère version
            personne.setVersion(1);
     
            //on attend 10 ms - pour les tests mettre true au lieu de false
            if (true) wait(10);
     
            //on insère la nouvelle perosnne dans la table de la BD
            getSqlMapClientTemplate().insert("Personne.insertOne", personne);        
        }
     
        //modifier une personne
        protected void updatePersonne(Personne personne) {
            //on attend 10 ms - pour les tests mettre true au lieu de false
            if (true) wait(10);
            /*
            try 
            {
                synchronized(this){ wait(10); }
            }
            catch(InterruptedException e) { }
            */
            //modification
            int n = getSqlMapClientTemplate().update("Personne.updateOne", personne);
     
            if (n==0) throw new DaoException("La personne d'Id ["+personne.getId()+" n'existe pas ou bien a été modifié", 2);
        }
     
        //vérifier validité d'une personn
        private void check(Personne p) {
            // personne p
            if (p == null) {
                    throw new DaoException("Personne null", 10);
            }
            // id
            if (p.getId() != -1 && p.getId() < 0) {
                    throw new DaoException("Id [" + p.getId() + "] invalide", 11);
            }
            // date de naissance
            if (p.getDateNaissance() == null) {
                    throw new DaoException("Date de naissance manquante", 12);
            }
            // nombre d'enfants
            if (p.getNbEnfants() < 0) {
                    throw new DaoException("Nombre d'enfants [" + p.getNbEnfants()
                                    + "] invalide", 13);
            }
            // nom
            if (p.getNom() == null || p.getNom().trim().length() == 0) {
                    throw new DaoException("Nom manquant", 14);
            }
            // prénom
            if (p.getPrenom() == null || p.getPrenom().trim().length() == 0) {
                    throw new DaoException("Prénom manquant", 15);
            }
        }
     
        // attente
        private void wait(int N) {
                // on attend N ms
                try {
                        Thread.sleep(N);
                } catch (InterruptedException e) {
                        // on affiche la trace de l'exception
                        e.printStackTrace();
                        return;
                }
        }
     
    }
    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
     
    package istia.st.springmvc.personnes.dao;
     
    public class DaoException extends RuntimeException
    {
        private int code;
     
        public int getCode() {
            return code;
        }
     
        public DaoException(String message, int code) {
            super(message);
            this.code = code;
        }
     
    }
    Les classes et interfaces pour configurer la transaction:
    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
     
    package istia.st.springmvc.personnes.service;
     
    import istia.st.springmvc.personnes.entites.Personne;
     
    import java.util.Collection;
     
    public interface IService {
    	// liste de toutes les personnes
    	Collection getAll();
     
    	// obtenir une personne particuli�re
    	Personne getOne(int id);
     
    	// ajouter/modifier une personne
    	void saveOne(Personne personne);
     
    	// supprimer une personne
    	void deleteOne(int id);
     
    	// ajouter plusieurs personnes
    	void saveMany(Personne[] personnes);
     
    	// supprimer plusieurs personnes
    	void deleteMany(int ids[]);
    }
    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
     
    package istia.st.springmvc.personnes.service;
     
    import istia.st.springmvc.personnes.entites.Personne;
    import istia.st.springmvc.personnes.dao.IDao;
     
    import java.util.Collection;
     
    public class ServiceImpl implements IService {
     
    	// la couche [dao]
    	private IDao dao;
     
    	public IDao getDao() {
    		return dao;
    	}
     
    	public void setDao(IDao dao) {
    		this.dao = dao;
    	}
     
    	// liste des personnes
    	public Collection getAll() {
    		return dao.getAll();
    	}
     
    	// obtenir une personne en particulier
    	public Personne getOne(int id) {
    		return dao.getOne(id);
    	}
     
    	// ajouter ou modifier une personne
    	public void saveOne(Personne personne) {
    		dao.saveOne(personne);
    	}
     
    	// suppression d'une personne
    	public void deleteOne(int id) {
    		dao.deleteOne(id);
    	}
     
    	// sauvegarder une collection de personnes
    	public void saveMany(Personne[] personnes) {
    		// on boucle sur le tableau des personnes
    		for (int i = 0; i < personnes.length; i++) {
    			dao.saveOne(personnes[i]);
    		}
    	}
     
    	// supprimer une collection de personnes
    	public void deleteMany(int[] ids) {
    		// ids : les id des personnes à supprimer
    		for (int i = 0; i < ids.length; i++) {
    			dao.deleteOne(ids[i]);
    		}
    	}
    }
    Les fichiers xml pour les beans:
    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
    63
    64
    65
    66
     
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
    "http://www.springframework.org/dtd/spring-beans.dtd">
    <beans>
        <!-- la source de données DBCP -->
        <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
            <property name="driverClassName">
                <value>com.mysql.jdbc.Driver</value>
            </property>
            <property name="url">
                <value>jdbc:mysql://192.168.1.199:3306/test</value>
            </property>
            <property name="username">
                <value>[LOGIN]</value>
            </property>
            <property name="password">
                <value>[MOT DE PASSE]</value>
            </property>
        </bean>
     
        <!-- SqlMapClient -->
        <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
            <property name="dataSource">
                <ref local="dataSource" />
            </property>        
            <property name="configLocation">
                <value>classpath:sql-map-config-mysql.xml</value>
            </property>
        </bean>
     
        <!-- la classe d'accès à la couche [dao] -->
        <bean id="dao" class="istia.st.springmvc.personnes.dao.DaoImplCommon">
            <property name="sqlMapClient">
                <ref local="sqlMapClient" />
            </property>
        </bean>
     
        <!-- gestionnaire de transactions -->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource">
                <ref local="dataSource" />
            </property>
        </bean>
     
        <!-- la classe d'accès à la couche [service] -->
        <bean id="service" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
            <property name="transactionManager">
                <ref local="transactionManager" />
            </property>
            <property name="target">
                <bean class="istia.st.springmvc.personnes.service.ServiceImpl">
                    <property name="dao">
                        <ref local="dao" />
                    </property>
                </bean>
            </property>
            <property name="transactionAttributes">
                <props>
                    <prop key="get*">PROPAGATION_SUPPORTS,readOnly</prop>
                    <prop key="save*">PROPAGATION_REQUIRED</prop>
                    <prop key="delete*">PROPAGATION_REQUIRED</prop>
                </props>
            </property>
        </bean>
    </beans>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    <?xml version="1.0" encoding="UTF-8"?>
    <!-- <!DOCTYPE sqlMapConfig PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN" 
    "http://www.ibatis.com/dtd/sql-map-config-2.dtd"> -->
     
    <!DOCTYPE sqlMapConfig PUBLIC "-//iBATIS.com//DTD SQL MAP Config 2.0//EN"
    "http://www.ibatis.com/dtd/sql-map-config-2.dtd">
    <sqlMapConfig>
        <sqlMap resource="personne-mysql.xml" />        
    </sqlMapConfig>
    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
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
     
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE sqlMap
    	PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN"
    	"http://ibatis.apache.org/dtd/sql-map-2.dtd">
     
    <sqlMap>
        <!-- alias classe [Personne] -->
        <typeAlias alias="Personne.classe" type="istia.st.springmvc.personnes.entites.Personne" />
     
        <!-- mapping table [PERSONNES] - objet [Personne] -->
        <resultMap id="Personne.map" class="istia.st.springmvc.personnes.entites.Personne">
            <result property="id" column="ID" />
            <result property="version" column="VERSION" />
            <result property="nom" column="NOM" />
            <result property="prenom" column="PRENOM" />
            <result property="dateNaissance" column="DATENAISSANCE" />
            <result property="marie" column="MARIE" />
            <result property="nbEnfants" column="NBENFANTS" />
        </resultMap>
     
        <!-- LISTE DE TOUTES LES PERSONNES -->
        <select id="Personne.getAll" resultMap="Personne.map">
            SELECT
            ID,
            VERSION,
            NOM,
            PRENOM,
            DATENAISSANCE,
            MARIE,
            NBENFANTS
            FROM
            PERSONNES
        </select>
     
        <!-- obtenir une personne en particulier -->
        <select id="Personne.getOne" resultMap="Personne.map">
            SELECT
            ID,
            VERSION,
            NOM,
            PRENOM,
            DATENAISSANCE,
            MARIE,
            NBENFANTS
            FROM
            PERSONNES
            WHERE ID=#value#
        </select>
     
        <!-- ajouter une personne -->
        <insert id="Personne.insertOne" parameterClass="Personne.classe">
            INSERT INTO
            PERSONNES
            (VERSION, NOM, PRENOM, DATENAISSANCE, MARIE, NBENFANTS)
            VALUES
            (#version#, #nom#, #prenom#, #dateNaissance#, #marie#, #nbEnfants#)
            <selectKey keyProperty="id">
                select LAST_INSERT_ID() as value
            </selectKey>    
        </insert>
     
        <!-- mettre à jour une personne -->
        <update id="Personne.updateOne" parameterClass="Personne.classe">
            UPDATE
            PERSONNES
            SET
            VERSION=#version#+1,
            NOM=#nom#,
            PRENOM=#prenom#,
            DATENAISSANCE=#dateNaissance#,
            MARIE=#marie#,
            NBENFANTS=#nbEnfants#
            WHERE ID=#id#
              AND VERSION=#version#
        </update>
     
        <!-- supprimer une perosnne -->
        <delete id="Personne.deleteOne" parameterClass="int">
            DELETE
            FROM 
            PERSONNES
            WHERE ID=#value#
        </delete>
     
        <!-- obtenir la valeur de la clé primaire [id] de la dernière personne insérée -->
        <select id="Personne.getNextId" resultClass="int">
            SELECT LAST_INSERT_ID()
        </select>
    </sqlMap>
    Et enfin le prog. principal:
    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
     
    package istia.st.springmvc.personnes.tests;
     
    import istia.st.springmvc.personnes.dao.IDao;
    import istia.st.springmvc.personnes.entites.Personne;
     
    import istia.st.springmvc.personnes.service.IService;
    import java.util.Collection;
    import java.util.Iterator;
     
    import org.springframework.beans.factory.xml.XmlBeanFactory;
    import org.springframework.core.io.ClassPathResource;
    import org.springframework.jdbc.datasource.DataSourceTransactionManager;
    import org.springframework.transaction.interceptor.TransactionProxyFactoryBean;
     
    public class MainTestServiceDao {
    	public static void main(String[] args) {
                    IService service= (IService) new XmlBeanFactory(new ClassPathResource("spring-config-dao-mysql.xml")).getBean("service");
     
                    Personne pers = service.getOne(424);
                    pers.setNbEnfants(15);
                    service.saveOne(pers);               
    	}
    }

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2006
    Messages : 48
    Points : 48
    Points
    48
    Par défaut
    J'ai fini par trouver une solution, ... pas super élégante mais à priori ca fonctionne.

    1) créer un sql statement pour le "LOCK TABLE"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    [...]
     
        <statement id="executeRawSql">
     
        $sql$    
     
        </statement>
     
    [...]
    2) Ajouter dans la classe DaoImplCommon une propriété m'indiquant si un "lock table" est en cours ou non:
    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
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
     
    package istia.st.springmvc.personnes.dao;
     
     
     
    import com.mysql.jdbc.Connection;
     
    import istia.st.springmvc.personnes.entites.Personne;
     
    import java.util.ArrayList;
     
    import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;
     
     
     
    import java.util.Collection;
     
    import java.util.List;
     
     
     
    public class DaoImplCommon extends SqlMapClientDaoSupport implements IDao
     
    {
     
        private boolean lock_table_performed=false;
     
     
     
        public boolean isLock_table_performed() {
     
            return lock_table_performed;
     
        }
     
    [...]
     
        @Override
     
        public void saveOne(Personne personne) {
     
            // le paramètre personne est-il valide ?
     
            check(personne);
     
     
     
            //if (true) wait(5000);
     
            //System.out.println("On attend 5 sec");
     
     
     
            //ajout ou modification ?
     
            if (personne.getId()==-1)
     
                insertPersonne(personne);
     
            else updatePersonne(personne);
     
        }
     
     [...]
     
     
     
        //ajouter une personne
     
        protected void insertPersonne(Personne personne) {
     
            //1ère version
     
            personne.setVersion(1);
     
     
     
            //on attend 10 ms - pour les tests mettre true au lieu de false
     
            if (true) wait(10);
     
     
     
            //on insère la nouvelle perosnne dans la table de la BD
     
            getSqlMapClientTemplate().insert("Personne.insertOne", personne);        
     
        }
     
     
     
        //modifier une personne
     
        protected void updatePersonne(Personne personne) {
     
            //on attend 10 ms - pour les tests mettre true au lieu de false
     
            if (true) wait(10);
     
            //modification
     
            lock_table_performed=true;
     
            getSqlMapClientTemplate().update("executeRawSql", "lock table personnes write");
     
            System.out.println("dans updatePersonne: lock table en cours...");
     
            if (true) wait(5000);
     
            int n = getSqlMapClientTemplate().update("Personne.updateOne", personne);
     
     
     
            if (n==0) throw new DaoException("La personne d'Id ["+personne.getId()+" n'existe pas ou bien a été modifié", 2);
     
        }
     
     
     
    [...]    
     
        //vérifier validité d'une personn
     
        private void check(Personne p) {
     
            // personne p
     
            if (p == null) {
     
                    throw new DaoException("Personne null", 10);
     
            }
     
            // id
     
            if (p.getId() != -1 && p.getId() < 0) {
     
                    throw new DaoException("Id [" + p.getId() + "] invalide", 11);
     
            }
     
            // date de naissance
     
            if (p.getDateNaissance() == null) {
     
                    throw new DaoException("Date de naissance manquante", 12);
     
            }
     
            // nombre d'enfants
     
            if (p.getNbEnfants() < 0) {
     
                    throw new DaoException("Nombre d'enfants [" + p.getNbEnfants()
     
                                    + "] invalide", 13);
     
            }
     
            // nom
     
            if (p.getNom() == null || p.getNom().trim().length() == 0) {
     
                    throw new DaoException("Nom manquant", 14);
     
            }
     
            // prénom
     
            if (p.getPrenom() == null || p.getPrenom().trim().length() == 0) {
     
                    throw new DaoException("Prénom manquant", 15);
     
            }
     
        }
     
     
     
        // attente
     
        private void wait(int N) {
     
                // on attend N ms
     
                try {
     
                        Thread.sleep(N);
     
                } catch (InterruptedException e) {
     
                        // on affiche la trace de l'exception
     
                        e.printStackTrace();
     
                        return;
     
                }
     
        }
     
     
     
    }
    3) Utiliser le postInterceptor pour exécuter un "UNLOCK TABLE" puisque cette commande doit être envoyé au serveur de BDD après la commande "COMMIT" sinon cela provoque un "COMMIT" par défaut...
    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
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
     
    /*
     
     * To change this template, choose Tools | Templates
     
     * and open the template in the editor.
     
     */
     
    package istia.st.springmvc.personnes.tests;
     
     
     
    import istia.st.springmvc.personnes.dao.DaoImplCommon;
     
    import istia.st.springmvc.personnes.service.ServiceImpl;
     
    import java.lang.reflect.Method;
     
    import java.sql.ResultSet;
     
    import org.springframework.aop.AfterReturningAdvice;
     
    public class TestInterceptorAfter implements AfterReturningAdvice 
     
    {
     
     
     
        @Override
     
        public void afterReturning(Object o, Method method, Object[] os, Object o1) throws Throwable 
     
        {
     
            for(int i=0;i<os.length;i++)
     
                System.out.println("after 01("+i+"):"+os[i].toString());
     
     
     
            if (o!=null)
     
                System.out.println("After 02:"+o.toString());
     
            else System.out.println("After 02: null");
     
     
     
            if (o1!=null)
     
                System.out.println("After 03:"+o1.toString());        
     
            else System.out.println("After 03: null");        
     
     
     
            ServiceImpl serv = (ServiceImpl) o1;
     
            DaoImplCommon sql = (DaoImplCommon) serv.getDao();
     
     
     
            ResultSet res = 
     
                sql.getDataSource().getConnection().prepareCall("SELECT connection_id()").executeQuery();
     
            res.first();
     
            System.out.println("after 04: connection_id(): "+res.getBigDecimal(1));
     
     
     
            res =
     
               sql.getSqlMapClientTemplate().getDataSource().getConnection().prepareCall("SELECT connection_id()").executeQuery();
     
            res.first();
     
            System.out.println("after 05: connection_id(): "+res.getBigDecimal(1));
     
     
     
            if (sql.isLock_table_performed())
     
                sql.getSqlMapClientTemplate().getDataSource().getConnection().prepareCall("UNLOCK TABLE").executeQuery();
     
        }
     
     
     
    }
    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
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
     
    <?xml version="1.0" encoding="UTF-8"?>
     
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
     
    "http://www.springframework.org/dtd/spring-beans.dtd">
     
    <beans>
    [...]
        <!-- la classe d'accès à la couche [service] -->
     
        <bean id="service" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
     
            <property name="transactionManager">
     
                <ref local="transactionManager" />
     
            </property>
     
            <property name="target">
     
                <bean class="istia.st.springmvc.personnes.service.ServiceImpl">
     
                    <property name="dao">
     
                        <ref local="dao" />
     
                    </property>
     
                </bean>
     
            </property>
     
            <property name="transactionAttributes">
     
                <props>
     
                    <prop key="get*">PROPAGATION_SUPPORTS,readOnly</prop>
     
                    <prop key="save*">PROPAGATION_REQUIRED</prop>
     
                    <prop key="delete*">PROPAGATION_REQUIRED</prop>
     
                </props>
     
            </property>
     
            <property name="preInterceptors">
     
                <list>
     
                    <ref local="intBefore" />
     
                </list>
     
            </property>
     
            <property name="postInterceptors">
     
                <list>
     
                    <ref local="intAfter" />
     
                </list>
     
            </property>        
     
        </bean>
     
     
     
        <bean id="intBefore" class="istia.st.springmvc.personnes.tests.TestInterceptorBefore" />
     
        <bean id="intAfter" class="istia.st.springmvc.personnes.tests.TestInterceptorAfter" />
     
    </beans>
    Si vous avez une meilleur solution je suis preneur...

Discussions similaires

  1. Réponses: 1
    Dernier message: 27/07/2012, 15h06
  2. comment gérer plusieurs locks sur une table?
    Par charluber dans le forum Oracle
    Réponses: 4
    Dernier message: 18/04/2006, 21h28
  3. Comment supprimer un verrou sur une table ?
    Par Laure13 dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 13/03/2006, 15h10
  4. Réponses: 2
    Dernier message: 08/02/2006, 21h22
  5. Faire un Lock sur une table pendant l'exec d'un DTS
    Par Pete dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 14/03/2005, 14h17

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