ObjectNotFoundException second level cache sleep with a large number of concurrent transactions

We have a Java application that uses MySQL, Hibernate (3.5.1-Final) and EHcache (1.2.3) for our second level cache.

Isolation level hibernate.properties is isolation with read commit = 2

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

With a large number of parallel transactions, we see a problem when certain collections (DB associations) throw an ObjectNotFoundException when loading, and it seems that the second-level cache returns an old copy of this collection.

We have many different types of transactions that access this collection (read-only) and only a couple that will add / remove elements from it.

We do not consider this problem when loading a single transaction or even in a moderate transactional load (10-20 simultaneous connections).

For example, we have a Character object:

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

We properly save the graph of objects when deleting entities, removing them from the collection in which they are contained, and calling session.delete ().

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

We tried to change the elements of Set; CacheConcurrencyStrategy from:

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

For

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

Bad luck.

We do not use database locks; instead, we use an optimistic concurrency control to catch and retry conflicting transactions.

The only 2 solutions that we see at this stage are:

  • Try to catch an ObjectNotFoundException and try to intelligently evict the collection (although there is not enough context in the exception)

  • Use the @NotFound (action = NotFoundAction.IGNORE) annotation over a collection of elements that will ignore and not raise an ObjectNotFoundException (but we are worried about how this works with the 2nd level cache and ensures that it searches for the corresponding data).

I'm sorry that there was no @NotFound (action = NotFoundAction.EVICT_2ND_LEVEL_CACHE_RELOAD), where it will dump this object from the cache and try to reload the collection.

We could also try changing FetchyType from LAZY to EAGER, but I want to try to understand the problem and choose the best solution that will ensure data consistency in our transactions under high concurrency.

+7
java concurrency hibernate ehcache second-level-cache
source share
1 answer

Perhaps you should try session.evict(characterItem) instead of session.delete ?

+1
source share

All Articles