L2 cache collection status is sometimes not synchronized with the database

We use the EhCachesecond level ( 4.3.8.Final) cache in Hibernate( 4.3.8.Final) for queries (read tables only), entities and collections between objects.

So you can say that the second level cache is heavily used for optimization purposes.

We have never encountered big problems so far ...

Our persistence model relative to the corresponding objects basically looks as follows:

  • First, we have 2 entities that have a bi-directional mapping in the natural parent-child relationship:

    @Entity
    @Table(...)
    @Cacheable
    @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
    public class Parent extends BaseEntity {
        @Id
        private long id;
    
        @OneToMany(mappedBy="parent", fetch=FetchType.LAZY, cascade = CascadeType.REMOVE)
        @Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
        private Set<Child> children;
    
        // getters and setters
    }
    
    @Entity
    @Table(...)
    @Cacheable
    @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
    public class Child extends BaseEntity {
        @Id
        private long id;
    
        @ManyToOne(fetch = FetchType.LAZY, optional = false)
        @JoinColumn(name = "parent_id", nullable = false)
        private Parent parent;
    
        // getters and setters
    }
    
  • Next we have some InvokingEntitythat has unidirectional mapping in Parententity

         @Entity
         @Table(...)
         @Cacheable
         @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
         public class InvokingEntity extends BaseEntity {
             @Id
             private long id;
    
             @Fetch(FetchMode.SUBSELECT)
             @OneToMany(fetch = FetchType.LAZY, mappedBy = "invokingEntity", cascade = CascadeType.ALL, orphanRemoval = true)
             @OrderBy("sequence asc")
             @SortComparator(ParentBySequenceComparator.class)
             @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
             private Set<Parent> parents = new TreeSet<>();
    
             // getters and setters
         }
    

Entities BaseEntity, , id version optimistic locking .


, :

A ChildRepository Child , ; (trx1):

:

 public void deleteChildsById(List<Long> childIds) {
    if (!childIds.isEmpty()) {
        getSession().createQuery("delete Child as child where child.id in (:childIds)")
                    .setParameterList("childIds", childIds)
                    .setReadOnly(false)
                    .executeUpdate();
    }
} 

create:

public void createChilds(List<Child> childs) {
    for (Child child : childs) {
        getSession().save(child);
    }
}

2- (trx2) :

InvokingEntity invokingEntity = getSession.get(InvokingEntity.class, someId);
Collection<Child> childs = invokingEntity.getFirstParent().getChilds();

, childs ( trx2) Child trx1.

, 2nd level cache DB. , 10% . , trx2 4-5 trx1.

? , ?

Hibernate, 2nd level cache , , , L2 // , .

EhCache config :

    <defaultCache maxElementsInMemory="10000"
              eternal="false"
              timeToIdleSeconds="1800"
              timeToLiveSeconds="3600"
              overflowToDisk="true"
              diskPersistent="false"
              diskSpoolBufferSizeMB="10"
              diskExpiryThreadIntervalSeconds="120"
              memoryStoreEvictionPolicy="LRU">
    </defaultCache>

, - ! !

+4

Source: https://habr.com/ru/post/1616386/


All Articles