Accès aux données et transactions

Une fois qu'une application dispose d'une référence à une instance ObjectGrid ou d'une connexion client à une grille distante, vous pouvez accéder aux données et interagir avec celles-ci dans votre grille de données. A l'aide de l'API ObjectGridManager, vous pouvez créer une instance locale ou établir une connexion client vers une instance répartie. Pour créer une instance locale, utilisez l'une des méthodes createObjectGrid. Pour établir une connexion client avec une grille de données distante, utilisez la méthode getObjectGrid.

L'unité d'exécution d'une application requiert sa propre Session. Lorsque vous souhaitez que l'application utilise ObjectGrid sur une unité d'exécution, appelez l'une des méthodes getSession pour obtenir une session. Lorsque l'application n'utilise plus la session, utilisez la méthode Session.close(). Cette méthode ferme la session, la renvoie au pool et libère ses ressources. La fermeture d'une session est facultative, mais elle améliore les performances des appels suivants vers la méthode getSession(). Si l'application utilise une structure d'injection de dépendance telle que Spring, vous pouvez injecter une Session dans le bean d'une application lorsque cette opération est nécessaire.

Lorsque vous avez obtenu une Session, l'application peut accéder aux données stockées dans des mappes de la grille d'objets. Si la grille utilise des entités, vous pouvez utiliser l'API EntityManager, que vous pouvez obtenir à l'aide de la méthode Session.getEntityManager. L'interface EntityManager étant plus proche des spécifications Java, elle est plus simple que l'API fondée sur les mappes. Toutefois, elle consomme davantage de ressources car elle effectue un suivi des modifications apportées aux objets. L'API fondée sur les mappes s'obtient à l'aide de la méthode Session.getMap.

WebSphere eXtreme Scale utilise des transactions. Lorsqu'une application interagit avec une Session, elle doit se trouver dans le contexte d'une transaction. Une transaction est initiée, puis validée ou annulée à l'aide des méthodes Session.begin, Session.commit et Session.rollback dans l'objet Session. Les applications peuvent également utiliser le mode de validation automatique, dans lequel la Session initie et valide automatiquement une transaction lorsque l'application interagit avec des mappes. Le mode de validation automatique est toutefois plus lent.

Logique d'utilisation des transactions

Les transactions peuvent paraître lentes. Utilisez les transactions pour les raisons suivantes :
  1. Pour pouvoir annuler des modifications en cas d'exception ou si la logique métier requiert l'annulation d'une modification d'état.
  2. Pour placer des verrous sur les données et les libérer tout au long de la durée de vie d'une transaction, afin que les modifications soient apportées de manière atomique (toutes les modifications sont appliquées, ou aucune).
  3. Pour générer une unité atomique de réplication.

Vous pouvez personnaliser la quantité de support de transaction nécessaire. Une application peut désactiver la prise en charge de l'annulation et le verrouillage, mais elle prend cette décision à ses dépens. Elle doit alors gérer elle-même l'absence de ces fonctions.

Une application peut par exemple désactiver le verrouillage en associant la stratégie de verrouillage de la mappe de sauvegarde à la valeur NONE. Cette stratégie est rapide, mais plusieurs transactions simultanées peuvent désormais modifier les mêmes données sans protection les unes des autres. L'application est responsable du verrouillage et de la cohérence des données lorsque NONE est utilisé.

Une application peut également modifier la façon dont les objets sont copiés lorsque la transaction y accède. L'application utilise la méthode ObjectMap.setCopyMode pour définir le mode de copie. Cette méthode vous permet de désactiver CopyMode. Cette opération est généralement utilisée pour les transactions en lecture seule si différentes valeurs peuvent être renvoyées pour le même objet au cours d'une même transaction. Différentes valeurs peuvent être renvoyées pour le même objet au cours d'une transaction.

Par exemple, si la transaction a appelé la méthode ObjectMap.get pour un objet à l'instant T1, elle a obtenu la valeur de cet instant précis. Si elle appelle à nouveau la méthode get à l'instant T2, une autre unité d'exécution peut avoir modifié cette valeur. Suite à cette modification, l'application voit une valeur différente. Si l'application modifie un objet récupéré à l'aide de la valeur CopyMode NONE, elle modifie directement la copie validée de cet objet. Dans ce mode, l'annulation de la transaction n'a aucune signification. Vous modifiez la seule copie dans la grille d'objets. Bien que l'utilisation de CopyMode NONE soit rapide, vous devez en mesurer les conséquences. Une application utilisant ce mode ne doit jamais annuler la transaction. Si elle le fait, les modifications ne sont pas reportées dans l'index et ne sont pas répliquées si la réplication est activée. Les valeurs par défaut sont plus simples à utiliser et risquent d'entraîner moins d'erreurs. Si vous favorisez les performances au détriment de la fiabilité des données, l'application doit savoir comment réagir afin d'éviter tout problème non intentionnel.

ATTENTION :
Soyez prudent lorsque vous modifiez les valeurs associées au verrouillage ou à CopyMode. Si vous les modifiez, l'application se comporte de manière non prévisible.

Interaction avec les données stockées

Dès que vous avez obtenu une session, vous pouvez utiliser le fragment de code suivant pour insérer des données à l'aide de l'API Map.

Session session = ...;
ObjectMap personMap = session.getMap("PERSON");
session.begin();
Person p = new Person();
p.name = "John Doe";
personMap.insert(p.name, p);
session.commit();

Le même exemple, mais utilisant cette fois l'API EntityManager, est présenté ci-dessous. Cet exemple de code suppose que l'objet Person est mappé vers une entité.

Session session = ...;
EntityManager em = session.getEntityManager();
session.begin();
Person p = new Person();
p.name = "John Doe";
em.persist(p);
session.commit();

Ce modèle est conçu pour obtenir des références aux ObjectMaps pour les mappes avec lesquelles l'unité d'exécution travaille, pour démarrer une transaction, utiliser les données, puis valider la transaction.

L'interface ObjectMap contient les opérations put, get et remove habituelles. Nous vous recommandons toutefois d'utiliser des noms d'opérations plus précis tels que get, getForUpdate, insert, update et remove. Ces méthodes permettent d'exécuter des opérations plus précises que les API Map habituelles.

Vous pouvez également utiliser la prise en charge de l'indexation, qui est flexible.

Voici un exemple de mise à jour d'un objet :

session.begin();
Person p = (Person)personMap.getForUpdate("John Doe");
p.name = "John Doe";
p.age = 30;
personMap.update(p.name, p);
session.commit();

L'application utilise normalement la méthode getForUpdate plutôt que la simple méthode get pour verrouiller un enregistrement. La méthode de mise à jour doit être appelée pour fournir la valeur mise à jour à la mappe. Si tel n'est pas le cas, la mappe n'est pas modifiée. Voici le même fragment de code, utilisant cette fois l'API EntityManager :

session.begin();
Person p = (Person)em.findForUpdate(Person.class, "John Doe");
p.age = 30;
session.commit();

L'API EntityManager est plus simple que l'API Map. Avec EntityManager, eXtreme Scale recherche l'entité et renvoie un objet géré à l'application. Celle-ci modifie l'objet et valide la transaction, et eXtreme Scale suit automatiquement les modifications apportées aux objets gérés lors de la validation et effectue les mises à jour nécessaires.

Transactions et partitions

Les transactions WebSphere eXtreme Scale peuvent mettre à jour une partition unique. Les transactions provenant d'un client peuvent lire plusieurs partitions, mais elles ne peuvent en mettre à jour qu'une seule. Si une application tente de mettre à jour deux partitions, la transaction échoue et est annulée. Une transaction utilisant un ObjectGrid imbriqué (logique de grille) ne dispose d'aucune fonction de routage et voit uniquement les données de la partition locale. Cette logique métier peut toujours obtenir une seconde session, qui est alors une véritable session client permettant d'accéder aux autres partitions. Cette transaction reste toutefois indépendante.

Requêtes et partitions

Si une transaction a déjà recherché une entité, elle est associée à la partition de cette entité. Les requêtes s'exécutant sur une transaction associée à une entité sont acheminées vers la partition associée.

Si une requête est exécutée sur une transaction avant d'être associée à une partition, vous devez définir l'ID de partition à utiliser pour cette requête. Cet ID est un nombre entier. La requête est alors acheminée vers cette partition.

Les requêtes exécutent des recherches dans une seule partition. Toutefois, vous pouvez utiliser les API DataGrid pour exécuter la même requête en parallèle sur toutes les partitions ou sur un sous-ensemble de partitions. Utilisez ces API pour rechercher une entrée pouvant se trouver sur n'importe quelle partition.

Le service de données REST permet aux clients HTTP d'accéder à la grille WebSphere eXtreme Scale. Ce service est compatible avec WCF Data Services dans Microsoft .NET Framework 3.5 SP1. Pour plus d'informations, voir Configuration des services de données REST.

.