Validation d’entité, verrouillage optimiste et cohérence de la requête dans Spring Data Couchbase

Les données]

  • lien:/tag/couchbase/[Couchbase]

1. Introduction

Après notre lien:/spring-data-couchbase[introduction à Spring Data Couchbase], ce deuxième tutoriel porte sur la prise en charge de la validation d’entité (JSR-303), le verrouillage optimiste et différents niveaux de cohérence des requêtes pour une base de documents Couchbase. .

2. Validation d’entité

Spring Data Couchbase prend en charge les annotations de validation d’entité JSR-303. Pour tirer parti de cette fonctionnalité, nous avons d’abord ajouté la bibliothèque JSR-303 à la section des dépendances de notre projet Maven:

<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>1.1.0.Final</version>
</dependency>

Ensuite, nous ajoutons une implémentation de JSR-303. Nous allons utiliser l’implémentation d’Hibernate:

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>5.2.4.Final</version>
</dependency>

Enfin, nous ajoutons un bean factory de validateur et l’écouteur d’événements Couchbase correspondant à notre configuration Couchbase:

@Bean
public LocalValidatorFactoryBean localValidatorFactoryBean() {
    return new LocalValidatorFactoryBean();
}

@Bean
public ValidatingCouchbaseEventListener validatingCouchbaseEventListener() {
    return new ValidatingCouchbaseEventListener(localValidatorFactoryBean());
}

La configuration XML équivalente ressemble à ceci:

<bean id="validator"
  class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>

<bean id="validatingEventListener"
  class="org.springframework.data.couchbase.core.mapping.event.ValidatingCouchbaseEventListener"/>

Nous ajoutons maintenant des annotations JSR-303 à nos classes d’entités. Lorsqu’une violation de contrainte est rencontrée pendant une opération de persistance, l’opération échouera en lançant une ConstraintViolationException .

Voici un exemple des contraintes que nous pouvons appliquer impliquant nos entités Student :

@Field
@NotNull
@Size(min=1, max=20)
@Pattern(regexp="^[a-zA-Z .'-]+$")
private String firstName;

...
@Field
@Past
private DateTime dateOfBirth;

3. Verrouillage optimiste

Spring Data Couchbase ne prend pas en charge les transactions multi-documents similaires à celles que vous pouvez réaliser dans d’autres modules Spring Data, tels que Spring Data JPA (via l’annotation @ Transactional ), et ne fournit pas de fonctionnalité de restauration.

Cependant, il prend en charge le verrouillage optimiste à peu près de la même manière que les autres modules Spring Data via l’utilisation de l’annotation @ Version :

@Version
private long version;

Sous les couvertures, Couchbase utilise ce que l’on appelle un mécanisme «de comparaison et d’échange» (CAS) pour obtenir un verrouillage optimiste au niveau de la banque de données.

Chaque document dans Couchbase a une valeur CAS associée qui est modifiée automatiquement chaque fois que les métadonnées ou le contenu du document sont modifiés.

L’utilisation de l’annotation @ Version sur un champ entraîne le remplissage de ce champ avec la valeur CAS actuelle lorsqu’un document est extrait de Couchbase.

Lorsque vous essayez de sauvegarder le document dans Couchbase, ce champ est comparé à la valeur CAS actuelle dans Couchbase. Si les valeurs ne correspondent pas, l’opération de persistance échouera avec une OptimisticLockingException .

Il est extrêmement important de noter que vous ne devriez jamais tenter d’accéder ou de modifier ce champ dans votre code.

4. Cohérence de la requête

Lorsque vous implémentez une couche de persistance sur Couchbase, vous devez prendre en compte la possibilité de lectures et d’écrits obsolètes. En effet, lorsque des documents sont insérés, mis à jour ou supprimés, la mise à jour des vues de sauvegarde et des index peut prendre un certain temps pour refléter ces modifications.

Et si vous avez un grand ensemble de données soutenu par un cluster de nœuds Couchbase, cela peut devenir un problème important, notamment pour un système OLTP.

Spring Data fournit un niveau de cohérence robuste pour certaines opérations de référentiel et de modèle, ainsi que quelques options vous permettant de déterminer le niveau de cohérence de lecture et d’écriture acceptable pour votre application.

4.1. Niveaux de cohérence

Spring Data vous permet de spécifier différents niveaux de cohérence et de précision des requêtes pour votre application via l’énumération Consistency située dans le package org.springframework.data.couchbase.core.query .

Cette énumération définit les niveaux suivants de cohérence et de stabilité des requêtes, du moins strict au plus strict:

  • EVENTUALLY CONSISTENT__

  • ** les lectures périmées sont autorisées

  • ** les index sont mis à jour selon l’algorithme standard de Couchbase

  • UPDATE AFTER__

  • ** les lectures périmées sont autorisées

  • ** les index sont mis à jour après chaque demande

  • DEFAULT CONSISTENCY (identique à READ YOUR OWN WRITES )

  • READ YOUR OWN WRITES__

  • ** les lectures périmées ne sont pas autorisées

  • ** les index sont mis à jour après chaque demande

  • STRONGLY CONSISTENT__

  • ** les lectures périmées ne sont pas autorisées

  • ** les index sont mis à jour après chaque déclaration

4.2. Comportement par défaut

Prenons le cas où des documents ont été supprimés de Couchbase et que les vues et index de sauvegarde ne sont pas complètement mis à jour.

La méthode intégrée CouchbaseRepository deleteAll () ignore en toute sécurité les documents trouvés par la vue de sauvegarde mais dont la suppression n’a pas encore été reflétée.

De même, les méthodes intégrées CouchbaseTemplate findByView et findBySpatialView offrent un niveau de cohérence similaire en ne renvoyant pas les documents initialement trouvés par la vue de sauvegarde mais supprimés depuis.

Pour toutes les autres méthodes de modèle, méthodes de référentiel intégré et méthodes de requête de référentiel dérivées, selon la documentation officielle de Spring Data Couchbase 2.1.x, Spring Data utilise un niveau de cohérence par défaut de Consistency.READ YOUR OWN WRITES.__

Il est à noter que les versions précédentes de la bibliothèque utilisaient la valeur par défaut Consistency.UPDATE AFTER__.

Quelle que soit la version que vous utilisez, si vous avez des réserves quant à l’acceptation aveugle du niveau de cohérence fourni, Spring propose deux méthodes vous permettant de contrôler de manière déclarative le ou les niveaux de cohérence utilisés, comme décrit dans les sous-sections suivantes.

4.3. Paramètre de cohérence globale

Si vous utilisez des référentiels Couchbase et que votre application appelle à un niveau de cohérence plus élevé, ou si elle peut tolérer un niveau plus faible, vous pouvez redéfinir le paramètre de cohérence par défaut pour tous les référentiels en remplaçant la méthode getDefaultConsistency () dans votre configuration Couchbase.

Voici comment remplacer le niveau de cohérence global dans votre classe de configuration Couchbase:

@Override
public Consistency getDefaultConsistency() {
    return Consistency.STRONGLY__CONSISTENT;
}

Voici la configuration XML équivalente:

<couchbase:template consistency="STRONGLY__CONSISTENT"/>

Notez que le prix de niveaux de cohérence plus stricts est une latence accrue au moment de l’interrogation. Veillez donc à personnaliser ce paramètre en fonction des besoins de votre application.

Par exemple, un entrepôt de données ou une application de génération de rapports dans laquelle des données sont souvent ajoutées ou mises à jour uniquement dans un lot serait un bon candidat pour EVENTUALLY CONSISTENT , alors qu’une application OLTP devrait probablement tendre vers les niveaux plus stricts tels que READ YOUR OWN WRITES ou STRONGLY CONSISTENT__.

4.4. Implémentation personnalisée de la cohérence

Si vous avez besoin de paramètres de cohérence mieux définis, vous pouvez redéfinir requête par requête le niveau de cohérence par défaut en fournissant votre propre implémentation de référentiel pour les requêtes dont vous souhaitez contrôler le niveau de cohérence de manière indépendante et en utilisant Méthodes queryN1QL fournies par CouchbaseTemplate .

Implémentons une méthode de référentiel personnalisée appelée findByFirstNameStartsWith pour notre entité Student pour laquelle nous ne souhaitons pas autoriser les lectures obsolètes.

Commencez par créer une interface contenant la déclaration de méthode personnalisée:

public interface CustomStudentRepository {
    List<Student> findByFirstNameStartsWith(String s);
}

Ensuite, implémentez l’interface en définissant le paramètre Stale du SDK Java sous-jacent de Couchbase au niveau souhaité:

public class CustomStudentRepositoryImpl implements CustomStudentRepository {

    @Autowired
    private CouchbaseTemplate template;

    public List<Student> findByFirstNameStartsWith(String s) {
        return template.findByView(ViewQuery.from("student", "byFirstName")
          .startKey(s)
          .stale(Stale.FALSE),
          Student.class);
    }
}

Enfin, en faisant en sorte que votre interface de référentiel standard étende l’interface générique CrudRepository et votre interface de référentiel personnalisé, les clients auront accès à toutes les méthodes intégrées et dérivées de votre interface de référentiel standard, ainsi qu’à toutes les méthodes personnalisées que vous avez implémentées dans votre classe de référentiel personnalisé. :

public interface StudentRepository extends CrudRepository<Student, String>,
  CustomStudentRepository {
    ...
}

5. Conclusion

Dans ce didacticiel, nous avons montré comment implémenter la validation d’entité JSR-303 et obtenir une capacité de verrouillage optimiste lors de l’utilisation du projet de communauté Spring Data Couchbase.

Nous avons également évoqué la nécessité de comprendre la cohérence des requêtes dans Couchbase et nous avons présenté les différents niveaux de cohérence fournis par Spring Data Couchbase.

Enfin, nous avons expliqué les niveaux de cohérence par défaut utilisés par Spring Data Couchbase globalement et pour quelques méthodes spécifiques. Nous avons également montré des méthodes pour remplacer le paramètre de cohérence par défaut global, ainsi que pour redéfinir les paramètres de cohérence sur une base requête par requête. vos propres implémentations de référentiel personnalisé.

Vous pouvez visualiser le code source complet de ce didacticiel à l’adresse the GitHub .

Pour en savoir plus sur Spring Data Couchbase, visitez le site officiel du projet Spring Data Couchbase .