2010-06-24 15 views
7

Tenemos una aplicación Java que utiliza MySQL, Hibernate (3.5.1-Final) y EHcache (1.2.3) para nuestro segundo nivel de caché.Hibernate caché de segundo nivel ObjectNotFoundException con un alto número de transacciones simultáneas

Nuestro nivel hibernate.properties aislamiento se ha comprometido Leer-isolation = 2

# 2-Read committed isolation 
hibernate.connection.isolation=2 

Bajo un elevado número de transacciones simultáneas, estamos viendo un problema por el que algunas colecciones (asociaciones DB) cuando está cargado lanzará una ObjectNotFoundException y parece que la memoria caché de segundo nivel está devolviendo una copia anterior de esa colección.

Tenemos muchos tipos diferentes de transacciones que acceden a esta colección (solo lectura) y solo una pareja que agregará/eliminará elementos de la misma.

No vemos este problema bajo carga de transacción única o incluso carga de transacción moderada (10 - 20 conexiones concurrentes).

Por ejemplo, tenemos una entidad Carácter:

@Entity 
@Table(name = "CHARACTERS") 
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) 
public class Character extends AbstractCharacter implements Serializable { 
... 
    @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) 
    @OneToMany(mappedBy = "character", cascade = CascadeType.ALL, fetch = FetchType.LAZY) 
    private Set<CharacterItem> items; 

Estamos manteniendo adecuadamente el gráfico de objetos cuando se eliminan las entidades retirándolos de la colección que están contenidas en Session.delete y llamar a().

character.getItems().remove(characterItem); 
    session.delete(characterItem); 

Hemos intentado cambiar los elementos del Set; CacheConcurrencyStrategy de:

@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) 
private Set<CharacterItem> items; 

Para

@Cache(usage = CacheConcurrencyStrategy.READ_WRITE) 
private Set<CharacterItem> items; 

sin suerte.

No usamos bloqueos de bases de datos, sino que usamos optimistic concurrency control para atrapar y reintentar transacciones conflictivas.

El sólo 2 soluciones que podemos ver en este punto es:

  1. intente coger el ObjectNotFoundException y tratar de desalojar a la colección inteligente (aunque no parece ser lo suficientemente contexto en el la excepción)

  2. Usar la @NotFound(action=NotFoundAction.IGNORE) anotación en la colección de artículos, que ignorará y no tirar la ObjectNotFoundException (pero tenemos preocupaciones en cuanto a cómo funciona esto con el segundo nivel de Ca che y asegúrese de que está buscando los datos adecuados).

Me gustaría que hubiera una @NotFound (acción = NotFoundAction.EVICT_2ND_LEVEL_CACHE_RELOAD) donde sería desalojar a ese objeto de la caché e intentar recargar la colección.

También podríamos tratar de cambiar el FetchyType de LAZY a EAGER pero quiero tratar de entender el problema y elegir la mejor solución que proporcionará que los datos en nuestras transacciones sean consistentes bajo alta concurrencia.

+0

¿Alguna vez resolvió esto correctamente? Tengo el mismo problema. – cherouvim

Respuesta

1

Quizás debería probar session.evict(characterItem) en lugar de session.delete?

Cuestiones relacionadas