jeudi 23 février 2023

[Spring Data] Optimistic locking and org.hibernate.StaleObjectStateException

L'optimistic locking est une technique utilisée pour gérer les conflits de concurrence dans les systèmes de bases de données. Elle permet à plusieurs utilisateurs d'accéder simultanément aux mêmes données sans bloquer l'accès à d'autres utilisateurs. L'optimistic locking est souvent utilisée dans les applications Web où plusieurs utilisateurs peuvent accéder à la même ressource simultanément. Dans cet article, nous allons discuter de l'optimistic locking en relation avec Spring Data et comment résoudre l'erreur org.hibernate.StaleObjectStateException.

1. Définition de l'optimistic locking

L'optimistic locking est une technique de gestion de conflits de concurrence qui permet à plusieurs transactions d'accéder simultanément à une ressource partagée. Dans le cas où plusieurs transactions tentent de modifier la même ressource simultanément, l'optimistic locking permet de détecter les conflits et de les résoudre en gérant la version des données. L'optimistic locking utilise généralement des indicateurs de version pour détecter les conflits. Chaque fois qu'une transaction modifie une ressource, l'indicateur de version est incrémenté. Si une autre transaction tente de modifier la même ressource, mais avec une version différente, un conflit est détecté et une exception est lancée.

2. Les avantages et inconvénients de l'optimistic locking

    Avantages :

    • Meilleure performance : Contrairement à la méthode de verrouillage pessimiste, l'optimistic locking ne verrouille pas l'enregistrement en base de données, ce qui permet une utilisation plus efficace des ressources et améliore les performances.
    • Plus grande concurrence : L'optimistic locking permet à plusieurs transactions d'accéder simultanément à la même ressource, ce qui augmente la concurrence et donc la disponibilité de la ressource.
    • Meilleure gestion des conflits : En cas de conflit entre deux transactions qui tentent de mettre à jour le même enregistrement, l'optimistic locking offre la possibilité de gérer de manière plus souple et personnalisée la résolution de ce conflit.

    Inconvénients :

    • Risque de perte de données : Si deux transactions tentent de mettre à jour simultanément un même enregistrement, l'une d'entre elles risque de perdre ses modifications. Si cela se produit, la transaction perdante devra être annulée et les données devront être récupérées et retraitées.
    • Nécessité d'une gestion fine des conflits : Contrairement à la méthode de verrouillage pessimiste, qui évite les conflits en empêchant l'accès concurrent à la ressource, l'optimistic locking nécessite une gestion plus fine des conflits. Cette gestion peut être complexe et nécessiter des développements spécifiques.
    • Problèmes de performance en cas de conflits fréquents : Si les conflits sont fréquents, l'optimistic locking peut entraîner des ralentissements de performances, car les transactions devront être annulées et les données devront être récupérées et retraitées plus souvent.

3. Quand on a l'erreur : [Spring Data] Optimistic locking et org.hibernate.StaleObjectStateException

L'erreur org.hibernate.StaleObjectStateException se produit lorsqu'une transaction tente de modifier une entité qui a été modifiée par une autre transaction entre le moment où la première transaction a chargé l'entité et le moment où elle tente de la modifier. Cette erreur est souvent associée à l'optimistic locking

Dans le contexte de Spring Data, l'optimistic locking est implémenté à travers l'utilisation de la propriété version des entités, qui est un champ qui contient un numéro de version des données. Lorsqu'une entité est modifiée, la version est automatiquement incrémentée, et lorsqu'une transaction tente de modifier des données, le numéro de version de l'entité est comparé à celui stocké en base de données. Si les deux numéros de version diffèrent, cela signifie que les données ont été modifiées par une autre transaction, et une exception est levée.

L'exception levée dans ce cas est org.hibernate.StaleObjectStateException, qui est une exception Hibernate qui indique qu'une tentative de mise à jour a échoué en raison d'un conflit de concurrence. Cette exception peut être interceptée dans le code de l'application pour gérer le conflit de manière appropriée, en réessayant la mise à jour, en informant l'utilisateur de l'échec de l'opération, ou en effectuant toute autre action pertinente.

Pour activer l'optimistic locking dans une entité Spring Data, il suffit d'ajouter l'annotation @Version au champ correspondant à la propriété version. L'exemple suivant montre l'implémentation d'une entité Person avec une propriété version :

Java
@Entity
public class Person {
@Id
@GeneratedValue
 private Long id;
 private String name;
 @Version
private Long version;
// getters and setters }

Dans cet exemple, la propriété version est représentée par un champ de type Long annoté avec @Version. Lorsqu'une transaction tente de modifier une instance de Person, la valeur du champ version est automatiquement incrémentée, ce qui permet de gérer les conflits de concurrence.


4. Comment corriger l'erreur

Il existe plusieurs façons de résoudre l'erreur org.hibernate.StaleObjectStateException :

  • Rafraîchir l'entité : Dans certains cas, il peut être possible de résoudre le conflit en rechargeant l'entité à partir de la base de données avant de tenter de la modifier. Cela permet de s'assurer que les modifications les plus récentes sont prises en compte.
  • Utiliser l'optimistic locking : Si l'entité est déjà configurée pour l'optimistic locking, il est possible que la version de l'entité ait été modifiée entre le moment où la transaction a chargé l'entité


En conclusion, Spring Data fournit un support intégré pour l'optimistic locking. Il permet de détecter les conflits de concurrence lors de la mise à jour d'une entité dans la base de données. Le mécanisme d'optimistic locking se base sur une colonne supplémentaire, généralement nommée version, qui est ajoutée à la table correspondant à l'entité.

Lorsqu'une entité est mise à jour, la version est incrémentée automatiquement par la base de données. Au moment de sauvegarder l'entité, Spring Data vérifie que la version stockée dans la base de données correspond à la version de l'entité qui est en train d'être sauvegardée. Si la version stockée dans la base de données est différente de la version de l'entité sauvegardée, cela signifie qu'un autre processus a mis à jour l'entité pendant que le processus actuel effectuait des modifications.

[Mockito] thenReturn vs thenAnswer

 tableau comparatif :

FonctionnalitéthenReturnthenAnswer
Syntaxewhen(mock.method()).thenReturn(value);when(mock.method()).thenAnswer(answer);
Renvoyer une valeurOuiOui
Répondre avec lambdaNonOui
ExceptionsthenThrow(Exception.class)thenThrow(Exception.class)
Vérification des appels de méthodeverify(mock).method()verify(mock, times(1)).method()
Vérification des paramètresverify(mock).method(expectedParam)verify(mock).method(argThat(matcher))
Utilisation pour les mock finauxNonOui
Possibilité de retourner des valeurs en fonction des argumentsNonOui
Risque de NullPointerException si la méthode mockée renvoie nullOuiNon
Erreurs d'utilisation potentiellesRetourne toujours la même valeur, peu utile pour des méthodes avec des effets de bordPeut être plus difficile à comprendre pour les débutants, risque de dépasser la portée des tests unitaires
Exempleswhen(mock.getAge()).thenReturn(25);when(mock.getAge()).thenAnswer(i -> 25);
Vérification des appels de méthode avec des paramètresverify(mock).setAge(25);verify(mock).setAge(argThat(matcher))

Note :

mercredi 22 février 2023

Assurer la sécurité de votre infrastructure Kubernetes de la phase de développement à la production avec "Snyk CLI"

 La sécurité est une préoccupation majeure dans le développement des applications, et cela est encore plus vrai pour les applications Kubernetes. Pour assurer la sécurité de votre application Kubernetes tout au long de son cycle de vie, il est important de scanner régulièrement les fichiers YAML de sécurité pour détecter les vulnérabilités et les failles de sécurité. Dans cet article, nous allons explorer comment utiliser Snyk CLI pour scanner les fichiers YAML de sécurité et assurer la sécurité de votre application Kubernetes, depuis le cycle de développement jusqu'à la production.

Installation de Snyk CLI Snyk CLI peut être installé sur différentes plateformes, notamment Windows, macOS et Linux, via les gestionnaires de paquets tels que Homebrew, npm ou directement en téléchargeant les binaires depuis le site web de Snyk. Pour installer Snyk CLI sur Windows, vous pouvez télécharger l'installateur à partir de leur site web, puis suivre les instructions d'installation. Une fois installé, vous pouvez utiliser Snyk CLI dans la ligne de commande en tapant snyk.

Authentification avec Snyk CLI Avant de pouvoir utiliser Snyk CLI pour scanner vos fichiers YAML de sécurité Kubernetes, vous devez vous connecter à Snyk CLI à l'aide de la commande snyk auth. Si vous n'avez pas encore de compte Snyk, vous pouvez en créer un gratuitement sur le site web de Snyk. Une fois connecté, vous pouvez commencer à scanner vos fichiers YAML de sécurité.

Scanner vos fichiers YAML de sécurité avec Snyk CLI Pour scanner un fichier YAML de sécurité Kubernetes, vous pouvez utiliser la commande snyk iac test, suivi du chemin vers votre fichier YAML de sécurité. Par exemple :

bash
snyk iac test k8s-security.yaml

La sortie de la commande affichera les vulnérabilités détectées dans votre fichier YAML de sécurité, y compris les détails sur les vulnérabilités et les correctifs recommandés. Vous pouvez également afficher les résultats dans un format JSON en utilisant l'option --json.

Intégration de Snyk CLI dans le cycle de développement Il est important d'intégrer la sécurité dès le début du cycle de développement. Une façon de le faire est d'intégrer Snyk CLI dans votre pipeline CI/CD. Par exemple, si vous utilisez Jenkins pour le déploiement de vos applications Kubernetes, vous pouvez intégrer Snyk CLI dans votre pipeline en ajoutant la commande de scan snyk iac test à l'étape de construction de votre pipeline.

De plus, vous pouvez également configurer des alertes de sécurité pour les vulnérabilités détectées dans vos fichiers YAML de sécurité en utilisant l'intégration Snyk avec des services tels que Slack, Jira, GitHub, etc.

Conclusion La sécurité est un élément essentiel dans le cycle de vie des applications, et Snyk CLI est un outil puissant pour scanner les fichiers YAML de sécurité Kubernetes. En intégrant Snyk CLI dans votre pipeline CI/CD et en configurant des alertes de sécurité, vous pouvez assurer la sécurité de votre application Kubernetes tout au long du cycle de vie, du développement à la production. Gardez à l'esprit que la sécurité est un processus continu, et il est important de scanner régulièrement les fichiers YAML