Question

Nous avons créé une couche de mise en cache à notre J2EE application. Dans ce cas, nous utilisons Ehcache. Cela a créé quelques défis.

Prenons cet exemple.

OrderItem orderitem = cache.getOrderItemByID("id");
OrderItem old_orderitem = cache.getOrderItemID("id");

orderitem.setStatus(1);
old_orderitem.setStatus(2);

Si nous ne sommes pas carefull, toute modification apportée à l'un de ces objets auront une incidence sur l'autre (ils font référence au même objet). OrderItem Enregistrement Retour à la dabase serait-il status = 2

Comment pourrions-nous résoudre ce la meilleure façon?

Nous avons essayé de faire une méthode .copyObject () pour chaque objet. Ce qui crée juste un nouvel objet et définit toutes les valeurs. Mais cela ne semble pas une bonne solution.

L'exemple était d'illustrer. Le code est beaucoup plus complexe que cela, mais le résultat est le même.

********************** Mise à jour 15.07.2010 ********************* *****************************

Dans EHCache 2 il y a quelques options pour allumer copyRead () et CopyWrite (). Et cela résout tous mes problèmes:)

Était-ce utile?

La solution

Ceci est un problème avec l'état mutable. Il n'est pas mise en cache seulement, il est tout moment, vous pouvez avoir plusieurs références au même objet et cet objet est mutable. Par exemple:

HashMap map = new HashMap();
map.put("one", new OrderItem());
OrderItem one = map.get("one");
OrderItem two = map.get("one");
one.setStatus(1);
two.setStatus(2);

aura exactement le même problème. Cela devient encore plus compliqué lorsque vous avez un environnement concurrent. Une façon de résoudre ce problème est d'avoir seulement des objets immuables. De cette façon, si vous voulez un objet état différent, vous allez devoir faire une nouvelle. Il rend également plus facile la programmation concurrente.

Vous avez raison de considérer la copie de l'objet. Vos options sont:

Chacun a ses forces et ses faiblesses et qui fonctionne le mieux dépend de votre environnement.

Autres conseils

On dirait que vous voulez mettre en cache les données représentant un objet (par exemple, les résultats d'une requête de base de données) plutôt qu'un objet lui-même (par exemple, les données de session pour un utilisateur que vous pouvez récupérer ailleurs).

Si tel est le cas, votre couche en tant que cache personnalisée (autour ehcache) doit créer un objet à partir des données de cache lorsqu'un utilisateur fait une demande - cela vous donnera un objet unique à chaque fois et vous ne l'interférence de l'objet .

Lorsque vous récupérez à partir du cache par id (getOrderItemById) Je suppose que cela signifie "faire l'objet uniquement identifié par id =?". Dans votre deuxième extrait que vous avez (ou essayez d'avoir?) 2 objets différents de sorte qu'il ressemble un peu que vous essayez de faire 2 choses contradictoires dans le code.

Vous pouvez appliquer l'unicité-Id = « ID » est toujours le même objet. Si vous définissez l'état et la remise à zéro, cela signifie que le même objet a un nouveau statut. Vous voudrez probablement étendre la méthode equals renvoie true si l'ID correspond aussi.

Vous pouvez également utiliser un drapeau « sale » pour marquer les objets qui ont été modifiés à partir du magasin de données (transactionnel?).

Faire une copie est pas une mauvaise façon de traiter ce soit, mais on ne sait pas ce que cela signifie d'avoir 2 objets courir avec le même identifiant. Peut-être que la copie doit être créé avec un identifiant nul pour indiquer qu'il n'existe pas dans le cache encore?

Quel est le bon comportement pour votre application?

Ehcache fournir un soutien pour les clés de verrouillage via une API de verrouillage explicite. Vous pouvez verrouiller sur la clé dans le cache avec lecture et d'écriture des verrous. Cela ne se verrouille pas sur la valeur dans le cache, de sorte que l'objet est toujours ouvert à une mutation si le programmeur en décide ainsi.

Cela peut ou ne peut pas résoudre le problème que vous mentionnez, selon la façon dont vous le voyez. Si le programmeur est wiling d'être discipliné, et utilise la lecture que les objets acquis à des fins de lecture et modifier + cache de mise à jour lorsque des objets acquis avec verrou en écriture sur la clé, cela devrait fonctionner.

Cependant, le problème de l'état mutable, comme jamie McCrindle mentionne, ne disparaît pas.

Référence: http://ehcache.org/documentation/explicitlocking.html

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top