Spring Transaction Aware кеш не работает - PullRequest
0 голосов
/ 11 октября 2019

Я использую абстракцию кеша с использованием Ehcache в качестве провайдера кеша. Я пытаюсь прикрепить операции кеша к весенним транзакциям JPA, но не могу этого сделать.

Даже при сбое транзакции / установке кэша отката.

Конфигурация,

        @Bean
    public EhCacheManagerFactoryBean cacheManagerUsingSpringApi() {
        EhCacheManagerFactoryBean ehCacheManagerFactoryBean = new EhCacheManagerFactoryBean();

        // provide xml file for ehcache configuration/
        ehCacheManagerFactoryBean.setConfigLocation(new ClassPathResource("spring-cache-abs-ehcache.xml"));

        return ehCacheManagerFactoryBean;
    }

    @Bean
    public org.springframework.cache.CacheManager ehCacheCacheManager() {
        final EhCacheCacheManager ehCacheCacheManager = new EhCacheCacheManager(cacheManagerUsingSpringApi().getObject());
        ehCacheCacheManager.setTransactionAware(true); // Setting  transaction aware
        return ehCacheCacheManager;
    }

spring-cache-abs-ehcache.xml,

    <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="ehcache.xsd"
         updateCheck="true"
         monitoring="autodetect"
         dynamicConfig="true">

    <cache name="EmployeeCache"
           maxEntriesLocalHeap="10000"
           eternal="false"
           timeToIdleSeconds="300" timeToLiveSeconds="600"
           memoryStoreEvictionPolicy="LFU"
           transactionalMode="off">
        <persistence strategy="localTempSwap" />
    </cache>
</ehcache>

EmployeeRepository,

    public interface EmployeeRepository extends JpaRepository<Employee, Long>, CustomEmployeeRepository {
    }

Транзакционный метод,

    @Repository
public class EmployeeRepositoryImpl implements CustomEmployeeRepository {

    @PersistenceContext
    private EntityManager entityManager;

    @Autowired
    private CacheManager cacheManager;

    // THIS METHOD SHOULD NOT PUT INTO CACHE WITH NEW NAME
    @Override
    @Transactional
    @Cacheable(cacheNames = "EmployeeCache", key = "#a0.id")
    public Employee customUpdate(Employee employee) {
        employee.setFirstName(UUID.randomUUID().toString());
        entityManager.merge(employee);

        // rolling back transaction 
        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

        return employee;
    }
}

Тестовый случай (вызывающий),

    @Test
public void testCustomUpdate() {
    // GIVEN
    Employee employee = new Employee();
    employee.setFirstName(UUID.randomUUID().toString());
    employee.setLastName(UUID.randomUUID().toString());
    final Employee savedEmployee = employeeRepository.save(employee);

    // WHEN
    final Employee updatedEmployee = employeeRepository.customUpdate(savedEmployee);

    // THEN
    final Cache employeeCache = cacheManager.getCache("EmployeeCache");
    final Cache.ValueWrapper object = employeeCache.get(updatedEmployee.getId());
    assertNull(object);
}

Тест должен пройти успешно, т. Е. Пружина не должна помещать данные вкэш в методе employeeRepository.customUpdate, если транзакция была откатом в этом методе. Но Spring помещает данные в кеш, даже если транзакции не удаются. ПРИМЕЧАНИЕ: Странно, если запись уже существует в кеше, то @CachePut не обновляет запись в кеше, если транзакция не удалась.

Итак, если я аннотирую employeeRepository.save с помощью @CachePut(cacheNames = "EmployeeCache", key = "#result.id")тогда кэш не обновляется в вызове обновления.

Чего здесь не хватает?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...