Dans notre application Java, nous utilisons une instruction SQL Server pour mettre en pause certains process.
C'est l'instruction SQL:
SELECT * FROM MESSAGES WITH (UPDLOCK, ROWLOCK) WHERE MESSAGES.INTERNAL_ID IN ('6f53448f-1c47-4a58-8839-e126e81130f0');
Les UUID dans la clause IN
changent bien sûr d'une exécution à l'autre.
C'est le code Java que nous utilisons pour le locking:
entityManager.createNativeQuery(sqlSsortingng).getResultList()
L'instruction SQL ci-dessus ne renvoie qu'une seule ligne. Malheureusement, il semble que toute la table est verrouillée. Le résultat est que tous les process sont verrouillés même si aucun ou seulement certains doivent être bloqués.
Pourquoi la table entière est-elle verrouillée même si je spécifie UPDLOCK
?
Information additionnelle:
MESSAGES.INTERNAL_ID
est NVARCHAR(255)
qui n'est pas Nullable. Sinon, il n'y a pas de contrainte sur la colonne. READ_COMMITTED
. C'est parce que votre MESSAGES.INTERNAL_ID
n'est pas une key. Une fois la ligne verrouillée, vous ne pouvez plus la lire et vérifier sa valeur. Essayez de créer une key primaire sur cette colonne.
Si c'est impossible, créez INDEX
dessus et réécrivez votre requête:
SELECT MESSAGES.INTERNAL_ID FROM MESSAGES WITH (UPDLOCK, ROWLOCK) WHERE MESSAGES.INTERNAL_ID IN ('6f53448f-1c47-4a58-8839-e126e81130f0');
MSDN dit:
Les indications de locking ROWLOCK, UPDLOCK et XLOCK qui acquièrent des verrous au niveau de la ligne peuvent placer des verrous sur les keys d'index plutôt que sur les lignes de données réelles. Par exemple, si une table a un index non cluster et qu'une instruction SELECT utilisant un indicateur de locking est traitée par un index de couverture, un verrou est acquis sur la key d'index dans l'index de couverture plutôt que sur la ligne de données dans la table de base.