Partager via


Accès concurrentiel optimiste

L’accès concurrentiel optimiste dérive son nom de l’hypothèse optimiste selon laquelle les collisions entre les transactions se produisent rarement ; une collision s’est produite lorsqu’une autre transaction met à jour ou supprime une ligne de données entre le moment où elle est lue par la transaction actuelle et l’heure à laquelle elle est mise à jour ou supprimée. C’est l’opposé de la concurrence pessimiste, ou du verrouillage, dans lequel le développeur de l’application croit que ces collisions sont courantes.

Dans l’accès concurrentiel optimiste, une ligne est laissée déverrouillée jusqu’à ce qu’il soit nécessaire de la mettre à jour ou de la supprimer. À ce stade, la ligne est relue et vérifiée pour voir si elle a été modifiée depuis sa dernière lecture. Si la ligne a changé, la mise à jour ou la suppression échoue et doit être réessayé.

Pour déterminer si une ligne a été modifiée, sa nouvelle version est vérifiée par rapport à une version mise en cache de la ligne. Cette vérification peut être basée sur la version de ligne, telle que la colonne timestamp dans SQL Server, ou les valeurs de chaque colonne de la ligne. De nombreux SGBD ne prennent pas en charge les versions de lignes.

La concurrence optimiste peut être implémentée par la source de données ou l'application. Dans les deux cas, l’application doit utiliser un niveau d’isolation de transaction faible, tel que Lecture validée ; l’utilisation d’un niveau supérieur annule l’augmentation de la concurrence acquise à l’aide de l’accès concurrentiel optimiste.

Si la concurrence optimiste est implémentée selon la source de données, l'application définit l'attribut de déclaration SQL_ATTR_CONCURRENCY sur SQL_CONCUR_ROWVER ou SQL_CONCUR_VALUES. Pour mettre à jour ou supprimer une ligne, il exécute une instruction de mise à jour ou de suppression positionnée ou appelle SQLSetPos comme avec une concurrence pessimiste ; le pilote ou la source de données retourne SQLSTATE 01001 (conflit d’opérations de curseur) si la mise à jour ou la suppression échoue en raison d’une collision.

Si l’application elle-même implémente la concurrence optimiste, elle définit l’attribut d’instruction SQL_ATTR_CONCURRENCY sur SQL_CONCUR_READ_ONLY pour lire une ligne. S’il compare les versions de ligne et ne connaît pas la colonne de version de ligne, il appelle SQLSpecialColumns avec l’option SQL_ROWVER pour déterminer le nom de cette colonne.

L’application met à jour ou supprime la ligne en augmentant l’accès concurrentiel à SQL_CONCUR_LOCK (pour obtenir un accès en écriture à la ligne) et en exécutant une instruction UPDATE ou DELETE avec une clause WHERE qui spécifie la version ou les valeurs de la ligne lorsque l’application l’a lue. Si la ligne a changé depuis, l'instruction échouera. Si la clause WHERE n’identifie pas de manière unique la ligne, l’instruction peut également mettre à jour ou supprimer d’autres lignes ; les versions de lignes identifient toujours de manière unique les lignes, mais les valeurs de ligne identifient de façon unique les lignes uniquement si elles incluent la clé primaire.