Redis кеш в классе обслуживания, кажется, не работает - PullRequest
1 голос
/ 13 октября 2019

Я учусь Redis. Сейчас сталкиваюсь с проблемой кеша redis. Я вызываю метод класса обслуживания с тем же значением, но кажется, что он выполняется каждый раз.

Когда я вызываю метод EmployEService getEmployeesByClient () из ThreadService, ожидаю нового клиента, которого я увижужурнал Внутри getEmployeeByClient . Но для следующего вызова я получу список из кэша, тогда он не будет выдавать данные из репозитория.

Но я получаю журнал Внутри getEmployeeByClient каждый раз, когда я вызываю методgetEmployeesByClient () EmployeeService с тем же аргументом. Я также предоставил свой журнал в конце этого раздела.

Я видел некоторые вопросы этого сайта, например: Не работает весеннее кэширование при загрузке в классе @Service

Но у меня нет решения.

Я предоставляю соответствующие коды:

Мой класс ThreadService:

@Service
@Slf4j
public class ThreadService implements Runnable {

    @Autowired
    private EmployeeService employeeService;

    public static boolean isRunning = true;

    @PostConstruct
    @Override
    public void run() {
        log.debug("Service Thread Started");
        while(isRunning) {
            log.debug("repository calling...");    
            List<Employee> employees = employeeService.getEmployeesByClient("FastVoiz");
            log.debug("Employee Size: " + employees.size());
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                log.error("Exception: ", e);
            }
        }
    }
}

Класс EmployeeService:

@Service
@Slf4j
public class EmployeeService {

    @Autowired
    private EmployeeRepository repository;

    @Cacheable(value = "employeeCache", key = "#client")
    public List<Employee> getEmployeesByClient(String client) {
        log.debug("Inside of getEmployeeByClient");
        return repository.findEmployeesByClient(client);
    }
}

Класс RedisConfiguration:

@Configuration
@EnableCaching
@PropertySource("classpath:application.properties")
public class RedisConfiguration {
    @Autowired
    private Environment env;

    @Bean
    public LettuceConnectionFactory redisConnectionFactory() {
        RedisStandaloneConfiguration redisConf = new RedisStandaloneConfiguration();
        redisConf.setHostName(env.getProperty("spring.redis.host"));
        redisConf.setPort(Integer.parseInt(env.getProperty("spring.redis.port")));
        redisConf.setPassword(RedisPassword.of(env.getProperty("spring.redis.password")));
        return new LettuceConnectionFactory(redisConf);
    }
    @Bean
    public RedisCacheConfiguration cacheConfiguration() {
        RedisCacheConfiguration cacheConfig = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofSeconds(600))
                .disableCachingNullValues();
        return cacheConfig;
    }
    @Bean
    public RedisCacheManager cacheManager() {
        RedisCacheManager rcm = RedisCacheManager.builder(redisConnectionFactory())
                .cacheDefaults(cacheConfiguration())
                .transactionAware()
                .build();
        return rcm;
    }
}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.9.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demoNaz</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demoNaz</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <maven.test.skip>true</maven.test.skip>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.4</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <!--to run jar file-->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
        <finalName>demoNaz</finalName>
    </build>

</project>

файл application.properties:

#JPA configuration
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=update
spring.jpa.hibernate.show-sql=true
spring.data.jpa.repositories.enabled=true
spring.jpa.database=POSTGRESQL
spring.jpa.show-sql=true
spring.jpa.generate-ddl=true
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
spring.jpa.properties.hibernate.id.new_generator_mappings=false
spring.jpa.properties.hibernate.format_sql=true 

#datasource
spring.datasource.url=jdbc:postgresql://localhost:5432/testDB
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.datasource.initialization-mode=always
#spring.datasource.initialize=true
#spring.datasource.schema=classpath:/schema.sql
spring.datasource.continue-on-error=true
spring.datasource.platform=postgres

#redis
spring.redis.host=localhost
spring.redis.timeout=2000
spring.redis.password=password
spring.redis.port=6379

#redis cache manager configuration
spring.cache.type=redis
spring.cache.redis.cache-null-values=false
spring.cache.redis.time-to-live=600000
spring.cache.redis.use-key-prefix=true

#redis-lettuce configuration
spring.redis.lettuce.pool.max-active=7 
spring.redis.lettuce.pool.max-idle=7
spring.redis.lettuce.pool.min-idle=2
spring.redis.lettuce.pool.max-wait=-1ms
spring.redis.lettuce.shutdown-timeout=200ms

#logging
logging.level.root=DEBUG
logging.file=demoApp.log

#others
spring.main.allow-bean-definition-overriding=true

Вот мой журнал:

2019-10-13 20:17:29.619 DEBUG 12932 --- [           main] c.example.demoNaz.service.ThreadService  : First line of thread
2019-10-13 20:17:29.619 DEBUG 12932 --- [           main] c.e.demoNaz.service.EmployeeService      : Inside of getEmployeeByClient
2019-10-13 20:17:29.620 DEBUG 12932 --- [           main] tor$SharedEntityManagerInvocationHandler : Creating new EntityManager for shared EntityManager invocation
2019-10-13 20:17:29.620 DEBUG 12932 --- [           main] o.h.q.c.internal.CriteriaQueryImpl       : Rendered criteria query -> select generatedAlias0 from Employee as generatedAlias0 where generatedAlias0.client=:param0
2019-10-13 20:17:29.620 DEBUG 12932 --- [           main] org.hibernate.SQL                        : select employee0_.id as id1_0_, employee0_.acc as acc2_0_, employee0_.client as client3_0_ from employee employee0_ where employee0_.client=?
Hibernate: select employee0_.id as id1_0_, employee0_.acc as acc2_0_, employee0_.client as client3_0_ from employee employee0_ where employee0_.client=?
2019-10-13 20:17:29.622 DEBUG 12932 --- [           main] org.hibernate.loader.Loader              : Result set row: 0
2019-10-13 20:17:29.622 DEBUG 12932 --- [           main] org.hibernate.loader.Loader              : Result row: EntityKey[com.example.demoNaz.entity.Employee#13002]
2019-10-13 20:17:29.622 DEBUG 12932 --- [           main] o.h.engine.internal.TwoPhaseLoad         : Resolving associations for [com.example.demoNaz.entity.Employee#13002]
2019-10-13 20:17:29.622 DEBUG 12932 --- [           main] o.h.engine.internal.TwoPhaseLoad         : Done materializing entity [com.example.demoNaz.entity.Employee#13002]
2019-10-13 20:17:29.623 DEBUG 12932 --- [           main] c.example.demoNaz.service.ThreadService  : Employee Size: 1
2019-10-13 20:17:32.258 DEBUG 12932 --- [l-1 housekeeper] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Pool stats (total=10, active=0, idle=10, waiting=0)
2019-10-13 20:17:34.623 DEBUG 12932 --- [           main] c.example.demoNaz.service.ThreadService  : First line of thread
2019-10-13 20:17:34.624 DEBUG 12932 --- [           main] c.e.demoNaz.service.EmployeeService      : Inside of getEmployeeByClient
2019-10-13 20:17:34.625 DEBUG 12932 --- [           main] tor$SharedEntityManagerInvocationHandler : Creating new EntityManager for shared EntityManager invocation
2019-10-13 20:17:34.625 DEBUG 12932 --- [           main] o.h.q.c.internal.CriteriaQueryImpl       : Rendered criteria query -> select generatedAlias0 from Employee as generatedAlias0 where generatedAlias0.client=:param0
2019-10-13 20:17:34.627 DEBUG 12932 --- [           main] org.hibernate.SQL                        : select employee0_.id as id1_0_, employee0_.acc as acc2_0_, employee0_.client as client3_0_ from employee employee0_ where employee0_.client=?
Hibernate: select employee0_.id as id1_0_, employee0_.acc as acc2_0_, employee0_.client as client3_0_ from employee employee0_ where employee0_.client=?
2019-10-13 20:17:34.628 DEBUG 12932 --- [           main] org.hibernate.loader.Loader              : Result set row: 0
2019-10-13 20:17:34.629 DEBUG 12932 --- [           main] org.hibernate.loader.Loader              : Result row: EntityKey[com.example.demoNaz.entity.Employee#13002]
2019-10-13 20:17:34.630 DEBUG 12932 --- [           main] o.h.engine.internal.TwoPhaseLoad         : Resolving associations for [com.example.demoNaz.entity.Employee#13002]
2019-10-13 20:17:34.630 DEBUG 12932 --- [           main] o.h.engine.internal.TwoPhaseLoad         : Done materializing entity [com.example.demoNaz.entity.Employee#13002]
2019-10-13 20:17:34.631 DEBUG 12932 --- [           main] c.example.demoNaz.service.ThreadService  : Employee Size: 1
2019-10-13 20:17:39.633 DEBUG 12932 --- [           main] c.example.demoNaz.service.ThreadService  : First line of thread
2019-10-13 20:17:39.633 DEBUG 12932 --- [           main] c.e.demoNaz.service.EmployeeService      : Inside of getEmployeeByClient

1 Ответ

1 голос
/ 14 октября 2019

Прежде всего, вы не должны использовать какие-либо из этих сервисов в фазе PostConstruct , потому что у вас нет гарантии, что прокси-перехватчик полностью запущен в этот момент. Если вам нужно что-то сделать, после инициализации контекста приложения попробуйте реализовать InitializingBean и переопределить метод afterPropertiesSet () или прослушать событие контекста приложения, например ContextRefreshedEvent . Начните свою тему там. Это гарантирует, что все остальные компоненты были инициализированы.

Теперь, перейдя к вашей проблеме, это происходит, потому что ваш перехватчик кеша не инициализирован. Обходное решение состоит в том, чтобы вручную инициализировать перехватчик. Для этого вы можете сделать что-то вроде этого,

    @Configuration
    public class ConfigClass{
        @Autowired
        private CacheInterceptor cacheInterceptor;

        @PostConstruct
        public void init(){

            cacheInterceptor.afterSingletonsInstantiated();
        }
    }

, это будет работать.

Также добавьте spring-boot-starter-cache в вашу зависимость https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-cache

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