redis學習系列--Redis 高併發下的,快取穿透問題解決方案
阿新 • • 發佈:2019-02-03
下面這段程式碼 如果1W個人同時訪問的話, 從redis 拿 allUser 時, userList為空時,那麼1W個人都要進入if判斷語句,查詢資料庫,資料庫壓力承受不住
package com.tb.service; import com.tb.dao.TUserMapper; import com.tb.pojo.TUser; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.util.List; @Service @Transactional public class TuserServicelmpl implements TuserService { @Resource private TUserMapper tUserMapper; @Resource private RedisTemplate redisTemplate; @Override public List<TUser> userlist() { //高併發下有點問題,此處問題:快取穿透 //查詢快取 List<TUser> userList = ( List<TUser>) redisTemplate.opsForValue().get("allUser"); if (userList==null){ //查詢資料庫 userList = tUserMapper.userlist(); redisTemplate.opsForValue().set("allUser",userList); } return userList; } }
解決方案
Synchronized 關鍵字
雙重檢測鎖 解決
package com.tb.service; import com.tb.dao.TUserMapper; import com.tb.pojo.TUser; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.util.List; @Service @Transactional public class TuserServicelmpl implements TuserService { @Resource private TUserMapper tUserMapper; @Resource private RedisTemplate redisTemplate; @Override public List<TUser> userlist() { //高併發下有點問題,此處問題:快取穿透 //查詢快取 List<TUser> userList = ( List<TUser>) redisTemplate.opsForValue().get("allUser"); //雙重檢測鎖 if (userList==null){ synchronized(this){ //從資料庫獲取資料 userList = ( List<TUser>) redisTemplate.opsForValue().get("allUser"); if (userList==null){ //快取為空,查詢資料庫 userList = tUserMapper.userlist(); redisTemplate.opsForValue().set("allUser",userList); } } } return userList; } }