|
Publicité ' | |||||||||||||||||||||||
|
|
#1 |
|
Membre habitué
![]() Inscription : septembre 2005 Messages : 514 ![]() |
Bonjour,
J'ai un petit souci d'accès concurrents avec 2 services windows utilisant la même table. Le but de ces services est de mettre à jour un montant (mais de 2 façons différentes). Dans le premier service, je procède de la façon suivante : SERVICE 1 étape 0 : Begin Transaction étape 1 - récupération du dernier montant enregistré : SELECT TOP 1 Montant FROM maTable WITH (tablockx) WHERE ... ORDER ... cela me renvoie un chiffre que j'appelle Montant1 étape 2 - calcul du nouveau montant Montant2 = Montant1 + x étape 3 - enregistrement du nouveau montant via une procédure stockée (c'est historique) : INSERT INTO [maTable] VALUES(Montant2) étape 4 - Commit Transaction SERVICE 2 je procède de la même façon : étape 0 : Begin Transaction étape 1 - récupération du dernier montant enregistré : SELECT TOP 1 Montant FROM maTable WITH (tablockx) WHERE ... ORDER ... cela me renvoie un nombre que j'appelle Montant3 étape 2 - calcul du nouveau montant Montant4 = Montant3 + y étape 3 - enregistrement du nouveau montant via un requête cette fois ci: INSERT INTO maTable VALUES(Montant4) étape 4 - Commit Transaction A priori, cela fonctionnait, sauf qu'hier, le 2 services se sont exécutés en même temps et que les accès concurrents, que je pensais gérés via le tablelockx, n'a pas fonctionné. Montant2 ET Montant4 ont été calculé à partir de la même valeur initialement récupérée dans ma table. Alors qu'avec une gestion correcte des accès concurrent, le service qui s'exécute en premier termine son exécution et l'insertion du nouveau montant dans la table avant que le second prenne la main et récupère le dernier montant enregistré (par le service 1) pour calculer, à son tour, le nouveau montant... Est-ce que à tout hasard, là, comme ça, y'a quelque chose qui vous saute aux yeux ? parce que n'étant pas expert en SQL Server, j'ai pensé, suite à mes diverses lectures, qu'un with tablelockx pouvait résoude mes problèmes... Mais je me suis manifestement gourré ! Merci de votre aide ! |
|
|
00
|
|
|
#2 |
![]() ![]() |
Le select, même s'il est dans une transaction, génère un verrou partagé... laissant de ce fait l'accès en lecture à un autre select.
Dans votre cas précis, il faut focer le verrouillage exclusif dès le select. Ceci ce fait via select ... with XLOCK Source Ce faisant, vous allez peut-être créer de la contention.... tout à un prix
__________________
Sr DBA Oracle / Sybase / MS-SQL / DB2 / Informix / Postgresql Administrateur SAP Attention : pas de réponse technique par MP : pensez aux autres, passez par les forums ! |
|
|
00
|
|
|
#3 |
![]() ![]() ![]() Nicolas SouquetAdministrateur de base de données Inscription : janvier 2005 Messages : 4 669 ![]() |
Bonjour,
Le mieux à mon sens et comme le suggère Fadace est plutôt de mettre SET TRANSACTION ISOLATION LEVEL REPEATABLE READ. Cela permet de le spécifier une bonne fois pour toutes. D'autre part on peut le changer en cours de route, et si l'on spécifie un indicateur de table, il prend priorité sur le niveau d'isolation de transaction @++
__________________
En bases de données relationnelles SQL, il n'y a ni tableaux, ni enregistrements, ni champs: il y a des tables, des lignes et des colonnes. Blog | Profil| Consulter ou télécharger les fichiers d'aide de SQL Server, des versions 2000 à 2012 |
|
00
|
|
|
#4 |
|
Membre habitué
![]() Inscription : septembre 2005 Messages : 514 ![]() |
Je vais regarder tout cela... Merci de vos conseils !!!
|
|
|
00
|
Copyright © 2000-2012 - www.developpez.com