Bonjour,

J'ai une question concernant les transactions serialized. J'ai mis en place une gestion de clefs comme expliqué par SQLpro dans son article : http://sqlpro.developpez.com/cours/clefs/

Voici un extrait du code de la procédure stockée de calcul de la prochaine clef :

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
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION SET_KEY
 
...
 
-- calcule de la nouvelle clef
SELECT @maxcle = MSK_LAST_VALUE +1
FROM   SYS_DB_MASTERKEY
WHERE  MSK_TABLE_NAME = @NOM_TABLE
 
-- mise à jour de la nouvelle clef dans la table des clefs
UPDATE SYS_DB_MASTERKEY
SET    MSK_LAST_VALUE = @maxcle
WHERE  MSK_TABLE_NAME = @NOM_TABLE
-- renvoi de la valeur de la clef
SELECT @maxcle
 
SET NOCOUNT OFF
 
COMMIT TRANSACTION SET_KEY
Dans une transaction SERIALIZABLE Il est dit que :

- Les instructions ne peuvent pas lire des données qui ont été modifiées mais pas encore validées par d'autres transactions.
- Aucune autre transaction ne peut modifier des données qui ont été lues par la transaction active tant que celle-ci n'est pas terminée.
- Les autres transactions ne peuvent pas insérer de nouvelles lignes avec des valeurs de clés comprises dans le groupe de clés lues par des instructions de la transaction active, tant que celle-ci n'est pas terminée.

La question est la suivante :
Une autre transaction peut elle lire des données lues par une transaction serializable ?

Que se passe t'il si cette procédure stockée est appelée par 2 applications en même temps et demande une clef sur une même table ?
Le
SELECT @maxcle = MSK_LAST_VALUE +1
FROM SYS_DB_MASTERKEY
WHERE MSK_TABLE_NAME = @NOM_TABLE

va t'il mettre un verrou sur la table ou la ligne ?

Ne faudrait il pas rajouter un indicateur de table UPDLOCK sur le select ?

Exemple de déroulement :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
 
T1                       T2
TRANS
select                   TRANS
                           select
update
COMMIT
                           update  <- Cet update la est il correct
                           COMMIT