Pergunta

Nós criamos uma camada de cache para o nosso J2EE-aplicação. Neste caso, usamos Ehcache. Isto criou alguns desafios.

Vamos dar este exemplo.

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

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

Se não estamos cuidado, todas as mudanças feitas a qualquer um desses objetos afetará o outro (eles fazem referência ao mesmo objeto). Salvando OrderItem volta ao dabase tornaria tem status = 2

Como vamos resolver isso da melhor maneira?

Nós tentamos fazer um método .copyObject () para cada objeto. Que apenas cria um novo objeto e define todos os valores. Mas isso não parece ser uma boa solução.

O exemplo foi apenas para ilustrar. O código é muito mais complexa do que isso, mas o resultado é o mesmo.

********************** 15.07.2010 Atualização ********************* *****************************

Em EHCache 2 há algumas opções para para ligar copyRead () e Copywrite (). E isso resolve todos os meus problemas:)

Foi útil?

Solução

Este é um problema com o estado mutável. Não é só o cache, é qualquer momento você pode ter várias referências ao mesmo objeto e esse objeto é mutável. Por exemplo:

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);

terá exatamente o mesmo problema. Isso se torna ainda mais complicado quando você tem um ambiente concorrente. Uma maneira de resolver isso é só para ter objetos imutáveis. Dessa forma, se você quer um objeto com estado diferente, você vai ter que fazer um novo. Ele também faz programação concorrente mais fácil.

Você tem razão para considerar copiar o objeto. Suas opções são:

Cada um tem seus pontos fortes e fracos e qual delas funciona melhor dependerá de seu ambiente.

Outras dicas

Parece que você deseja armazenar em cache os dados que representam um objeto (por exemplo, os resultados de uma consulta de banco de dados) em vez de um objeto em si (por exemplo, os dados da sessão para um usuário que você pode querer recuperar em outro lugar).

Se este for o caso, sua camada cacheing costume (cerca ehcache) precisa criar um objeto a partir dos dados de cache quando um usuário faz uma solicitação - isto lhe dará um objeto único de cada vez e você não terá interferência objeto .

Quando você recupera a partir do cache por id (getOrderItemById) eu supor que significa "obter o objeto exclusivamente identificado por id =?". Em seu segundo trecho tem (ou estão tentando ter?) 2 objetos diferentes de modo que parece um pouco como você está tentando fazer 2 coisas contraditórias no código.

Você poderia impor exclusividade-Id = "ID" é sempre o mesmo objeto. Se você definir o status e, em seguida, reiniciá-lo, isso significa que o mesmo objeto tem novo status. Você provavelmente gostaria de estender o método .equals para retornar verdadeiro se os jogos id também.

Você também pode usar um sinalizador "sujo" para objetos marca que foram alterados em relação ao (? Transacional) armazenamento de dados.

Fazer uma cópia não é uma má maneira de lidar com isso também, embora não está claro o que significa ter 2 objetos correndo com o mesmo id. Talvez a cópia deve ser criado com um id nula para indicar que não existe no cache ainda?

O que é o comportamento correto para sua aplicação?

Ehcache fornecer suporte para teclas de bloqueio através de uma API de bloqueio explícito. Você pode bloquear a chave no cache com leitura e gravação fechaduras. Isso não bloquear o valor do cache, de modo que o objeto ainda está aberto a mutação se o programador assim o decidir.

Isto pode ou não resolver o problema que você menciona, dependendo de como você vê-lo. Se o programador é wiling para ser disciplinado e usos ler adquiriu objetos apenas para fins de leitura e modificar + atualiza o cache quando adquiridos objetos com bloqueio de gravação na chave, então isso deve funcionar.

No entanto, o problema estado mutável, como Jamie McCrindle menciona, não vai embora.

Referência: http://ehcache.org/documentation/explicitlocking.html

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top