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 est dite avoir eu lieu 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 que la mise à jour ou la suppression de celle-ci soit terminée. À ce stade, la ligne est relue et case activée ed 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 case activée par rapport à une version mise en cache de la ligne. Cette case activée ing 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.

L’accès concurrentiel optimiste peut être implémenté 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 l’accès concurrentiel optimiste est implémenté par la source de données, l’application définit l’attribut d’instruction 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 l’accès concurrentiel 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 accéder 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 échoue. 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 manière unique uniquement les lignes s’ils incluent la clé primaire.