SQL 데이터베이스 캐시로 Redis--

첫째, 환경 springBoot :

  1) 오기 의존성 :

        <의존성> 
            <의 groupId> org.springframework.boot </의 groupId> 
            <artifactId를> 스프링 부팅 스타터 데이터 레디 스 </ artifactId를> 
        </ 의존성>
의지

  2) 프로필 application.yml

봄 : 
  레디 스 : 
    호스트 : 192.168.2.147 
    포트 : 6379 
    암호 : java1902의 
    jedis : 
      풀 : 
        최대 - 활동 : 100
application.yml

데이터베이스 캐시 등 두, 레디 스 :

  작동 방식 : 첫 번째 쿼리는 SQL에서 데이터가 변경, 빈 캐시 해당 레디 스를 재 취득 할 때까지 후속 쿼리에 대한 레디 스 데이터로 조회 완료 후, SQL 데이터베이스를 사용;

  캐시 무효화 : 캐시 레디 스 방식을 빈 사용하여 데이터베이스를 업데이트;

  1) 엔티티 클래스 :

공용  클래스 제품 구현 직렬화 {
     개인 정수 ID를;
    개인 문자열 이름; 

    대중 제품 () { 
    } 

    공공 제품 (정수 ID, 문자열 이름) {
          .ID = 아이디;
         .name을 = 이름; 
    } 

    공공 정수 getId () {
         반환 아이디; 
    } 

    공공  공극 setId (정수 ID) {
          .ID = ID; 
    } 

    공공 문자열 getName () {
         반환  이름;
    }

     공공  무효 에서는 setName (문자열 이름) {
          .name을 = 이름; 
    } 

    @Override 
    공공 문자열 toString () {
         반환 "제품 {"+ 
                "ID ="+ 아이디 + 
                ", 이름 = '"+ 이름 +'\ ''+ 
                '}' ; 
    } 
}
Entity 클래스

  2) 시험 :

@RunWith (SpringRunner. 클래스 ) 
@SpringBootTest 
공공  클래스 RedistestSpringData2ApplicationTests { 
    @Autowired 
    개인 RedisTemplate redisTemplate을;

    @Test 
    공공  무효 cacheTest () { 
        목록 . <제품 소개> 제품 = (목록 <제품 소개>) redisTemplate.opsForValue () ( "제품"수 );
        경우 (제품 == null이 ) { 
            에서 System.out.println ( "查询数据库......" );
            // 模拟从数据库查询数据 
            제품 = 새로운 ArrayList를 <제품 소개> (); 
            products.add ( 제품 (1, "商品1" )); 
            products.add (  제품 (2, "商品2" )); 

            redisTemplate.opsForValue () 세트 (. "제품" , 제품); 
        } 다른 { 
            에서 System.out.println ( "查询缓存......" ); 
        } 
    } 

    @Test 
    공공  무효 delCacheTest () { 
        redisTemplate.delete ( "제품" ); 
    } 

}

셋째, 해결 캐시 관통 질문 :

  잃어버린 시간이 캐시에 기록되지 않은 데이터베이스 정보를 접속하여 스레드를 조각, 반복 방문 다른 스레드 데이터베이스 액세스, 데이터베이스는 엄청난 압력을 발생 ;: 이유

  해결 방법 :

    1) 잠금 동기화 :이 분산되어 있기 때문에 개발을 동기화 범위는 여러 서비스를 통해 동기화 된 JVM은 무효입니다;

    2) 레디 스 분산 잠금 :

      1, 레디 스 지방의 사용 :   

setnx 잠금 1 // 1 
GET 잠금 // 1 
잠금 setnx 2 // 00 
델 잠금 
setnx 잠금 2 // 1

      2, springboot 코드 구현 :

        // 마지막으로 시도 교착 상태 문제를 해결 :

@RunWith (SpringRunner. 클래스 ) 
@SpringBootTest 
공공  클래스 RedistestSpringData2ApplicationTests { 
    @Autowired 
    개인 RedisTemplate redisTemplate을; 

    @Test 
    공개  공극 multiThreadTest () 가 발생 예외 : InterruptedException { 
        ExecutorService를 풀 = 새로운 ThreadPoolExecutor에 (100, 200, 100 , TimeUnit.MILLISECONDS,
                 새로운 LinkedBlockingDeque를 <> (100 ))을
        위한 ( int로 , I (100) <; I = 0 난 ++ ) { 
            pool.submit를 ( 새로운 의 Runnable () {
                @Override 
                공공  무효 실행 () { 
                    cacheTest (); 
                } 
            }); 
        } 
        에 Thread.sleep ( 1000000 ); 
    } 

    @Test 
    공공  무효 cacheTest () { 
        목록 . <제품 소개> 제품 = (목록 <제품 소개>) redisTemplate.opsForValue () ( "제품"수 );
        경우 (제품 == ) { 
            부울 ifAbsent = redisTemplate.opsForValue () setIfAbsent. ( "제품 : 잠금", 1 );
            경우 (ifAbsent) {
                 시도 {
                    에서 System.out.println ( "데이터베이스 쿼리 ......" );
                     // 데이터베이스 쿼리에서 아날로그 데이터 
                    제품 = 새로운 새로운 ArrayList를 <제품 소개> (); 
                    products.add ( 새 새 제품 (1, "제품 1" )) ; 
                    products.add ( 새 새 제품 (2, "제품 2" ));
                     int로 내가 = 10/0 ; 
                    redisTemplate.opsForValue () SET (. : "제품" ;, 제품) 
                } 최종적으로 { 
                    redisTemplate.delete ( "제품 : "잠금 );
                } 
            } 다른 {
                 시도 { 
                    Thread.sleep를 ( 1 ); 
                } 캐치 (예외 : InterruptedException 전자) { 
                    e.printStackTrace (); 
                } 
                cacheTest (); 
            } 
        } 다른 { 
            에서 System.out.println ( "查询缓存......" ); 
        } 
    } 

    @Test 
    공공  무효 delCacheTest () { 
        redisTemplate.delete ( "제품" ); 
    } 
}

넷째, 캐시 고장의 문제를 해결하기 위해 :

  그 이유는 반복되는 쿼리마다 다시 액세스 데이터베이스 널;

  해결 방법 : 값이 null 쿼리가 캐시로 레디 스에 빈 객체를 반환, 일정 시간이 만료 설정;

@RunWith (SpringRunner. 클래스 ) 
@SpringBootTest 
공공  클래스 RedistestSpringData2ApplicationTests { 
    @Autowired 
    개인 RedisTemplate redisTemplate을; 

    공공 제품 productById (정수 ID) {
         경우 (ID> 10 ) {
             반환  널 (null) ; 
        } 
        반환  ) (제품; 
    } 

    @Test 
    공개  공극 cachePenetrationTest () {
         위해 ( int로 난 = 11, I <20; i가 ++ ) { 
            제품 일반= (제품) redisTemplate.opsForValue () GET ( "제품". + I),
             IF (제품 == null이 ) {
                 // 데이터베이스 쿼리에서 아날로그 데이터 
                에서 System.out.println ( "데이터베이스 쿼리 ...... " );
                 // i가 10보다 큰 경우, 입력이 null 
                제품 = productById (I)
                 // 빈 경우는 null 때 
                IF (제품 == ) { 
                    제품 = 새로운 새로운 생성물 (I" " ); 
                    redisTemplate. . opsForValue () SET ( "제품"+ I, 제품); 
                    redisTemplate.expire ("제품"+ I, 10 , TimeUnit.MINUTES); 
                } 다른 { 
                    . redisTemplate.opsForValue () 세트 ( 이하 "제품"+ I, 제품); 
                    redisTemplate.expire ( 이하 "제품"+ I, 20 , TimeUnit.MINUTES); 
                } 
            } 다른 { 
                에서 System.out.println ( "查询缓存......" ); 
            } 
        } 
    } 

    @Test 
    공공  무효 delCacheTest () { 
        redisTemplate.delete ( "제품" ); 
    } 
}

 

추천

출처www.cnblogs.com/Tractors/p/11304252.html