1、redis基本配置:/project/src/main/resources/beans.redis : redis.xmljava
1 <?xml version="1.0" encoding="UTF-8" ?> 2 3 <beans 4 xmlns="http://www.springframework.org/schema/beans" 5 xmlns:tx="http://www.springframework.org/schema/tx" 6 xmlns:aop="http://www.springframework.org/schema/aop" 7 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 8 xmlns:context="http://www.springframework.org/schema/context" 9 xsi:schemaLocation=" 10 http://www.springframework.org/schema/beans 11 http://www.springframework.org/schema/beans/spring-beans-4.0.xsd 12 http://www.springframework.org/schema/context 13 http://www.springframework.org/schema/context/spring-context-4.0.xsd 14 http://www.springframework.org/schema/aop 15 http://www.springframework.org/schema/aop/spring-aop-4.0.xsd 16 http://www.springframework.org/schema/tx 17 http://www.springframework.org/schema/tx/spring-tx-4.0.xsd" 18 default-lazy-init="false"> 19 20 <!-- redis鏈接池的配置 --> 21 <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> 22 <!-- 最大鏈接數 --> 23 <property name="maxTotal" value="${redis.maxTotal}" /> 24 <!-- 最大空閒鏈接數 --> 25 <property name="maxIdle" value="${redis.maxIdle}" /> 26 <!-- 最小空閒鏈接數 --> 27 <property name="minIdle" value="${redis.minIdle}" /> 28 <!-- 獲取鏈接時的最大等待毫秒數,小於零:阻塞不肯定的時間,默認-1 --> 29 <property name="maxWaitMillis" value="${redis.maxWaitMillis}" /> 30 <!-- 在獲取鏈接的時候檢查有效性, 默認false --> 31 <property name="testOnBorrow" value="${redis.testOnBorrow}"/> 32 <!-- --> 33 <!-- <property name="testOnReturn" value="${redis.testOnReturn}"/> --> 34 </bean> 35 36 <!-- redis鏈接工廠 --> 37 <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"> 38 <!-- <property name="password" value="${redis.password}"/> --> 39 <property name="usePool" value="true"/> 40 <property name="hostName" value="${redis.host}" /> 41 <property name="port" value="${redis.port}" /> 42 <property name="poolConfig" ref="jedisPoolConfig" /> 43 </bean> 44 45 <!-- redis 操做模板 --> 46 <bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate"> 47 <property name="connectionFactory" ref="jedisConnectionFactory" /> 48 <property name="keySerializer"> 49 <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" /> 50 </property> 51 <property name="valueSerializer"> 52 <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" /> 53 </property> 54 </bean> 55 56 57 </beans>
2、資源文件(redis參數值配置):/project/src/main/resources/configs : redisServerConfig.propertieslinux
1 #可用鏈接實例的最大數目,默認值爲8 2 redis.maxTotal=512 3 #控制一個pool最多有多少個狀態爲idle(空閒的)的jedis實例,默認值也是8 4 redis.maxIdle=50 5 redis.minIdle=0 6 #等待可用鏈接的最大時間,單位毫秒,默認值爲-1,表示永不超時。若是超過等待時間,則直接拋出JedisConnectionException; 7 redis.maxWaitMillis=10000 8 #在borrow一個jedis實例時,是否提早進行validate操做;若是爲true,則獲得的jedis實例均是可用的; 9 redis.testOnBorrow=true 10 11 redis.host=192.168.17.246 12 redis.port=6379
3、redis封裝工具類:/yst_sit/src/main/java/utils : RedisUtils.javaweb
1 /** 2 * 3 */ 4 package kklazy.utils; 5 6 import java.util.List; 7 import java.util.Map; 8 import java.util.Map.Entry; 9 import java.util.Set; 10 import java.util.concurrent.TimeUnit; 11 12 import javax.annotation.Resource; 13 14 import org.springframework.data.redis.core.Cursor; 15 import org.springframework.data.redis.core.HashOperations; 16 import org.springframework.data.redis.core.ScanOptions.ScanOptionsBuilder; 17 import org.springframework.data.redis.core.StringRedisTemplate; 18 import org.springframework.data.redis.serializer.GenericToStringSerializer; 19 20 import com.alibaba.fastjson.JSON; 21 22 /** 23 * @author 24 * 緩存工具類 25 */ 26 @org.springframework.stereotype.Component 27 public class RedisUtils { 28 29 @Resource(name="redisTemplate") 30 private StringRedisTemplate redisTemplate; 31 32 public void test(){ 33 System.out.println("111"); 34 } 35 public <T> T get(String key, String hashKey, Class<T> cls) { 36 Object obj = redisTemplate.opsForHash().get(key, hashKey); 37 if (obj == null) { 38 return null; 39 } 40 41 return JSON.parseObject(obj.toString(), cls); 42 } 43 44 public <T> List<T> getList(String key, String hashKey, Class<T> cls) { 45 Object obj = redisTemplate.opsForHash().get(key, hashKey); 46 if (obj == null) { 47 return null; 48 } 49 50 return JSON.parseArray(obj.toString(), cls); 51 } 52 53 public String get(String key) { 54 redisTemplate.setValueSerializer(new GenericToStringSerializer<String>(String.class)); 55 Object obj = redisTemplate.opsForValue().get(key); 56 if (obj == null) { 57 return null; 58 } else { 59 return String.valueOf(obj); 60 } 61 } 62 63 public void set(String key,String value){ 64 redisTemplate.opsForValue().set(key, value); 65 } 66 67 public void set(String key,String value,int timeout){ 68 redisTemplate.opsForValue().set(key, value, timeout, TimeUnit.DAYS); 69 } 70 71 public void set(String key,String hashKey,Object value){ 72 HashOperations<String, Object, Object> hash = redisTemplate.opsForHash(); 73 hash.put(key, hashKey, value); 74 } 75 public void setMap(String key,Map<String,Object> map ){ 76 //添加 一個 hash集合 77 HashOperations<String, Object, Object> hash = redisTemplate.opsForHash(); 78 hash.putAll(key, map); 79 } 80 81 public String getMap(String key,String mapKey ){ 82 Object obj = redisTemplate.opsForHash().get(key, mapKey); 83 if (obj == null) { 84 return null; 85 } else { 86 return String.valueOf(obj); 87 } 88 } 89 public Map<Object, Object> getAllMap(String key){ 90 Map<Object, Object> obj = (Map<Object, Object>)redisTemplate.opsForHash().entries(key); 91 return obj; 92 93 } 94 95 96 public void delMap(String key,String mapKey){ 97 redisTemplate.opsForHash().delete(key, mapKey); 98 } 99 /** 100 * 根據 大key(精確匹配) + mapkey前綴(模糊匹配) 刪除緩存 101 * @param prex 102 */ 103 public void deleteMapByMapPrex(String key,String mapKeyPrex) { 104 ScanOptionsBuilder sob = new ScanOptionsBuilder(); 105 sob.match(mapKeyPrex+"*"); 106 Cursor<Entry<Object, Object>> test = redisTemplate.opsForHash().scan(key, sob.build()); 107 108 while(test.hasNext()){ 109 Entry<Object, Object> entry = test.next(); 110 String keyMap = (String) entry.getKey(); 111 Object valueMap = entry.getValue(); 112 System.out.println( key + "" + valueMap); 113 delMap(key,keyMap); 114 115 } 116 } 117 /** 118 * 根據key前綴模糊匹配redis key 119 * @param prex 120 * @return 121 */ 122 public Set<String> findByPrex(String prex){ 123 return redisTemplate.keys(prex+"*"); 124 } 125 126 public boolean isExists(String key){ 127 return redisTemplate.hasKey(key); 128 129 } 130 public boolean isExists(String key,String hashKey){ 131 return redisTemplate.opsForHash().hasKey(key, hashKey); 132 133 } 134 135 public void del(String key){ 136 redisTemplate.delete(key); 137 } 138 139 }
4、java代碼實現緩存更新(推送緩存、刪除緩存)redis
1.service:BaseBankPoscontrastService.java spring
1 /** 2 * 3 */ 4 package kklazy.acqinstmanagement.service; 5 6 import java.util.HashMap; 7 import java.util.List; 8 import java.util.Map; 9 10 import org.apache.commons.collections.CollectionUtils; 11 import org.apache.commons.lang3.StringUtils; 12 import org.hibernate.criterion.DetachedCriteria; 13 import org.hibernate.criterion.Restrictions; 14 import org.springframework.beans.factory.annotation.Autowired; 15 import org.springframework.stereotype.Service; 16 import org.springframework.transaction.annotation.Transactional; 17 18 import com.alibaba.fastjson.JSON; 19 20 import kklazy.acqinstmanagement.model.BaseBankPoscontrastConfig; 21 import kklazy.acqinstmanagement.model.BaseChannelParam; 22 import kklazy.acqinstmanagement.model.RoutePayforminfoConfig; 23 import kklazy.acqinstmanagement.model.BaseBankPoscontrast; 24 import kklazy.api.model.Merchant; 25 import kklazy.api.service.MerchantService; 26 import kklazy.persistence.callback.AssembleCriteriaParamsCallBack; 27 import kklazy.persistence.support.CommonResponse; 28 import kklazy.quas.service.DefaultQuasService; 29 import kklazy.utils.RedisUtils; 30 31 /** 32 * @author 33 * 34 */ 35 @Service 36 @Transactional(rollbackFor=Exception.class) 37 public class BaseBankPoscontrastService extends DefaultQuasService<BaseBankPoscontrast,String> { 38 39 40 @Autowired 41 private MerchantService merchantService; 42 @Autowired 43 private RoutePayforminfoConfigService routePayforminfoConfigService; 44 @Autowired 45 private BaseChannelParamService baseChannelParamService; 46 @Autowired 47 private RedisUtils redisUtils; 48 //更新緩存 49 public CommonResponse getPushCaching(BaseBankPoscontrast pos,String type,CommonResponse retval){ 50 String key="fmtct_"+pos.getFormid()+"_"+pos.getMerchantcodeIn()+"_"+pos.getTermnoIn()+"_"+pos.getChannelid()+"_"+pos.getTranstype(); 51 BaseBankPoscontrastConfig psc=new BaseBankPoscontrastConfig(); 52 Map<String,Object> map = new HashMap<String,Object>(); 53 RoutePayforminfoConfig rpc=new RoutePayforminfoConfig(); 54 rpc.setFormId(pos.getFormid()); 55 rpc.setMerchNo(pos.getMerchantcodeIn()); 56 rpc.setStatus("00"); 57 List<RoutePayforminfoConfig> rpclist=routePayforminfoConfigService.getRoutePayforminfoConfigs(rpc); 58 if(rpclist.size()!=1){ 59 retval.setResult(false); 60 retval.setMessage("平臺編碼爲:"+pos.getFormid()+",商戶號爲:"+pos.getMerchantcodeIn()+"時,查詢平臺商戶交易信息表(ROUTE_PAYFORMINFO_CONFIG)數據不是一條,請查詢"); 61 return retval; 62 } 63 Merchant merch=new Merchant(); 64 merch.setOrgCode(rpclist.get(0).getOrgCode()); 65 merch.setMerchNo(pos.getMerchantcodeIn()); 66 merch.setStatus("00"); 67 List<Merchant> merchant = merchantService.getMerchantsByCondition(merch); 68 if(merchant.size()!=1){ 69 retval.setResult(false); 70 retval.setMessage("該記錄對應的受理商戶數據不是一條,請查詢。機構號:"+rpclist.get(0).getOrgCode()+",商戶號:"+pos.getMerchantcodeIn()); 71 return retval; 72 } 73 psc.setChannelid(StringUtils.isNotBlank(pos.getChannelid()) ? pos.getChannelid():""); 74 psc.setFormid(StringUtils.isNotBlank(pos.getFormid()) ? pos.getFormid():""); 75 psc.setFormtype(StringUtils.isNotBlank(pos.getFormtype()) ? pos.getFormtype():""); 76 BaseChannelParam bcp=new BaseChannelParam(); 77 bcp.setChannelId(pos.getChannelid()); 78 List<BaseChannelParam> bcplist=baseChannelParamService.getBaseChannelParams(bcp); 79 psc.setFlag((CollectionUtils.isEmpty(bcplist)||StringUtils.isBlank(bcplist.get(0).getCode())) ? "" : bcplist.get(0).getCode()); 80 psc.setMerabbr((CollectionUtils.isEmpty(merchant)||StringUtils.isBlank(merchant.get(0).getSname())) ?"": merchant.get(0).getSname()); 81 psc.setMername((CollectionUtils.isEmpty(merchant)||StringUtils.isBlank(merchant.get(0).getCname())) ? "": merchant.get(0).getCname()); 82 psc.setMercatcode((CollectionUtils.isEmpty(rpclist)||StringUtils.isBlank(rpclist.get(0).getMccCode())) ? "": rpclist.get(0).getMccCode()); 83 psc.setMerchantcode_in((null == pos||StringUtils.isBlank(pos.getMerchantcodeIn())) ?"": pos.getMerchantcodeIn()); 84 psc.setMerchantcode_out((null == pos||StringUtils.isBlank(pos.getMerchantcodeOut())) ?"": pos.getMerchantcodeOut()); 85 psc.setTermno_in((null == pos||StringUtils.isBlank(pos.getTermnoIn())) ? "": pos.getTermnoIn()); 86 psc.setTermno_out((null == pos||StringUtils.isBlank(pos.getTermnoOut())) ? "": pos.getTermnoOut()); 87 psc.setTranstype((null == pos||StringUtils.isBlank(pos.getTranstype())) ? "": pos.getTranstype()); 88 89 if(type.equals("00")){ 90 //推緩存 91 System.out.println("原:key:"+key+",value:"+redisUtils.getMap("route_bank_poscontrast", key)); 92 redisUtils.set("route_bank_poscontrast", key, JSON.toJSONString(psc)); 93 System.out.println("Now:key:"+key+",value:"+redisUtils.getMap("route_bank_poscontrast", key)); 94 }else{ 95 //刪緩存 96 redisUtils.delMap("route_bank_poscontrast",key); 97 //判斷商戶路由數據結構key是否存在 98 if(redisUtils.isExists("route_bank_poscontrast",key)){ 99 retval.setResult(false); 100 retval.setMessage("刪除該緩存失敗,key爲:route_bank_poscontrast+"+key+"!!!"); 101 return retval; 102 } 103 System.out.println("刪除緩存成功:key爲:route_bank_poscontrast+"+key); 104 retval.setMessage("更新緩存成功"); 105 } 106 return retval; 107 } 108 109 }
2.controller:BaseBankPoscontrastController.java 數據庫
1 /** 2 * 3 */ 4 package kklazy.acqinstmanagement.controller; 5 6 import java.util.List; 7 8 import javax.annotation.Resource; 9 import javax.servlet.http.HttpServletRequest; 10 import javax.servlet.http.HttpServletResponse; 11 12 import org.apache.commons.collections.CollectionUtils; 13 import org.apache.commons.lang3.StringUtils; 14 import org.hibernate.criterion.DetachedCriteria; 15 import org.hibernate.criterion.MatchMode; 16 import org.hibernate.criterion.Restrictions; 17 import org.springframework.beans.factory.annotation.Autowired; 18 import org.springframework.data.domain.Page; 19 import org.springframework.data.domain.PageRequest; 20 import org.springframework.data.domain.Sort; 21 import org.springframework.data.domain.Sort.Direction; 22 import org.springframework.stereotype.Controller; 23 import org.springframework.ui.ModelMap; 24 import org.springframework.web.bind.annotation.PathVariable; 25 import org.springframework.web.bind.annotation.RequestMapping; 26 import org.springframework.web.bind.annotation.ResponseBody; 27 28 import kklazy.acqinstmanagement.model.RoutePayforminfoConfig; 29 import kklazy.acqinstmanagement.model.BaseBankPoscontrast; 30 import kklazy.acqinstmanagement.model.BaseBankPoscontrastParam; 31 import kklazy.acqinstmanagement.service.RoutePayforminfoConfigService; 32 import kklazy.acqinstmanagement.service.BaseBankPoscontrastService; 33 import kklazy.api.model.BaseChannelMerchant; 34 import kklazy.api.model.BaseOrg; 35 import kklazy.api.model.BaseTransType; 36 import kklazy.api.model.Merchant; 37 import kklazy.api.service.BaseChannelMerchantService; 38 import kklazy.api.service.BaseOrgService; 39 import kklazy.api.service.BaseTransTypeService; 40 import kklazy.api.service.MerchantService; 41 import kklazy.common.constants.ContextConstants; 42 import kklazy.common.controller.BasePageController; 43 import kklazy.merchentry.channel.institution.model.BaseChannelEntity; 44 import kklazy.merchentry.channel.institution.service.BaseChannelService; 45 import kklazy.persistence.callback.AssembleCriteriaParamsCallBack; 46 import kklazy.persistence.model.DefaultPageQueryModel; 47 import kklazy.persistence.service.PageService; 48 import kklazy.persistence.support.CommonResponse; 49 import kklazy.persistence.utils.DateUtils; 50 import kklazy.security.context.SecurityApplicationContext; 51 import kklazy.security.service.DictionaryService; 52 import kklazy.terminalinfo.modle.AcceptanceTerminalEntity; 53 import kklazy.terminalinfo.modle.AcceptanceTerminalPk; 54 import kklazy.terminalinfo.modle.TerminalChannelEntity; 55 import kklazy.terminalinfo.modle.TerminalChannelPk; 56 import kklazy.terminalinfo.service.AcceptanceTerminalService; 57 import kklazy.terminalinfo.service.TerminalChannelService; 58 59 /** 60 * @author 61 * 62 */ 63 @Controller 64 @RequestMapping("baseBankPoscontrast") 65 public class BaseBankPoscontrastController extends BasePageController<BaseBankPoscontrast,String> { 66 67 private static final String OPERATION_TYPE = "operationType"; 68 private static final String OPERATION_CREATE = "create"; 69 private static final String OPERATION_MODIFY = "modify"; 70 private static final String OPERATION_COPY_AND_CREATE = "copy_and_create"; 71 private static final String PAGE_TRANSTYPE = "transtypes"; 72 private static final String PAGE_FORMTYPE = "formtypes"; 73 private static final String PAGE_CHANNEL = "channels"; 74 private static final String PAGE_BASEORG = "baseorg"; 75 private static final String PAGE_CHANNEL_MERCHANT = "channelmerchant"; 76 private static final String PAGE_MERCHANT = "merchant"; 77 private static final String PAGE_BASE_TERMINAL= "baseTerminalList"; 78 private static final String PAGE_TERMINAL_CHANNEL= "terminalChannelList"; 79 @Autowired 80 public BaseBankPoscontrastService baseBankPoscontrastSerivce; 81 @Autowired 82 private BaseTransTypeService baseTransTypeService; 83 84 85 @Resource(name = "defaultBaseChannelService") 86 private BaseChannelService baseChannelService; 87 88 @Autowired 89 private BaseOrgService baseOrgService; 90 91 @Autowired 92 private BaseChannelMerchantService baseChannelMerchantService; 93 94 @Autowired 95 private MerchantService merchantService; 96 97 @Autowired 98 private RoutePayforminfoConfigService routePayforminfoConfigService; 99 100 @Autowired 101 private DictionaryService dictionaryService; 102 103 @Resource(name="acceptanceTerminalService") 104 private AcceptanceTerminalService acceptanceTerminalService; 105 106 @Resource(name="terminalChannelService") 107 private TerminalChannelService terminalChannelService; 108 109 @Override 110 public PageService<BaseBankPoscontrast, String> pageservice() { 111 return baseBankPoscontrastSerivce; 112 } 113 114 @Override 115 public String path() { 116 return "/webpages/acqinstmanagement/baseBankPoscontrast"; 117 } 118 119 120 /** 121 * 保存(修改功能暫時去掉,不可修改。目前只可新增數據和刪除數據(緩存同步)) 122 * @param request 123 * @param response 124 * @param modelMap 125 * @param entity 126 * @return 127 */ 128 @Override 129 protected CommonResponse commithandler(HttpServletRequest request, HttpServletResponse response, ModelMap modelMap, 130 BaseBankPoscontrast entity) { 131 retval = CommonResponse.SUCCESS(); 132 // 新增 133 if (OPERATION_CREATE.equals(request.getParameter(OPERATION_TYPE))) { 134 // 生成Id 135 // String id=DateUtils.format("yyMMdd")+baseBankPoscontrastSerivce.getSeqBaseBankPoscontrastId(); 136 // entity.setId(id); 137 // 狀態賦值爲00(正常) 138 entity.setStatus("00"); 139 entity.setFormtype("0001"); 140 // 增長建立時間 141 entity.setEntdate(DateUtils.currentDate()); 142 143 }
155 // 增長操做人 156 entity.setOperaname(SecurityApplicationContext.getEmployee().getName()); 157 try { 158 baseBankPoscontrastSerivce.merge(entity);//保存數據 159 } catch (Exception e) { 160 e.printStackTrace(); 161 retval.setMessage("保存數據失敗"); 162 retval.setResult(false); 163 return retval; 164 } 165 retval.setMessage("保存數據成功"); 166 try { 167 retval = baseBankPoscontrastSerivce.getPushCaching(entity,"00",retval); 168 } catch (Exception e) { 169 e.printStackTrace(); 170 retval.setMessage("保存數據成功,推送緩存失敗"); 171 retval.setResult(false); 172 return retval; 173 }//更新緩存 174 if(retval.isResult()){ 175 retval.setMessage("保存數據/推送緩存成功"); 176 } 177 178 return retval; 179 // return super.commithandler(request, response, modelMap, entity); 180 } 181 @Override 182 @ResponseBody 183 @RequestMapping({ "/delete/{id}" }) 184 public CommonResponse delete(HttpServletRequest request, HttpServletResponse response, ModelMap modelMap,@PathVariable String id) throws Exception { 185 //baseBankPoscontrastCheck pos= new baseBankPoscontrastCheck(); 186 retval = CommonResponse.SUCCESS(); 187 BaseBankPoscontrast pos= new BaseBankPoscontrast(); 188 try { 189 if(StringUtils.isNotBlank(id)){ 190 pos = service().findBy(id); 191 } 192 if(StringUtils.isNotBlank(pos.getStatus())){ 193 if ("00".equals(pos.getStatus())) { 194 pos.setStatus("01"); 195 } else { 196 pos.setStatus("00"); 197 } 198 } 199 200 pos.setUpddate(DateUtils.currentDate()); 201 pos.setOperaname(SecurityApplicationContext.getUsername()); 202 try { 203 baseBankPoscontrastSerivce.merge(pos); 204 } catch (Exception e) { 205 e.printStackTrace(); 206 retval.setMessage("更新數據庫失敗"); 207 retval.setResult(false); 208 return retval; 209 } 210 retval.setMessage("更新數據庫成功"); 211 //更新緩存 212 try { 213 retval = baseBankPoscontrastSerivce.getPushCaching(pos,pos.getStatus(),retval); 214 } catch (Exception e) { 215 e.printStackTrace(); 216 retval.setMessage("推送緩存失敗"); 217 retval.setResult(false); 218 return retval; 219 } 220 221 } catch (Exception e) { 222 logger.error(e.getMessage()); 223 return CommonResponse.FAILURE(); 224 } 225 if(retval.isResult()){ 226 retval.setMessage("更新數據庫/推送緩存成功"); 227 } 228 return retval; 229 } 230 231 232 }
5、更新緩存後,去緩存服務器去查看是否更新apache
1.經過安裝redis-desktop-manager.exe查看是否更新緩存json
2.secureCRT:登陸進服務器:輸入linux命令,根據key查詢是否更新緩存:redis-cli(中間不要有空格)------------>hget 大key 小keyapi
6、緩存數組操做數組
若推送的緩存信息一個key對應的記錄不止一條(多條),則一個key,對應value的值爲數組形式:
(1)一個key,對應一條記錄時:緩存形式:
key:fmtct_000000000009112_839290048990088__60000008_0014
value:{"channelid":"60000008","flag":"11","formid":"000000000009112","formtype":"0001","merabbr":"銀視通訊息科技有限公司","mercatcode":"5598","merchantcode_in":"839290048990088","merchantcode_out":"999888787787887","mername":"銀視通訊息科技有限公司","termno_in":"","termno_out":"","transtype":"0014"}
(2)一個key,對應多條記錄時:緩存形式:
key:pc_000000000009068_0001
value:[{"channelid":"30000001","core_trans_type":"0001","depth_match":"0","formid":"000000000009068","max_amt":"","min_amt":"","sort":"0","transtype":"0001"}]
or
key:pc_000000000005878_0003
value:
[{"channelid": "00000008","core_trans_type": "0006","depth_match": "0","formid": "000000000005878","max_amt": "2","min_amt": "1","sort": "0","transtype": "0003"},
{"channelid": "48392900","core_trans_type": "0003","depth_match": "2","formid": "000000000005878","max_amt": "","min_amt": "","sort": "0","transtype": "0003"}]
代碼:存入map由原來的一個key-dto(一個key對應一條記錄),改成key-list<dto>
1 /** 2 * 根據平臺商戶交易信息表查詢緩存信息推送緩存 3 * @param routePayforminfoConfig 4 * @return 5 */ 6 public CommonResponse payFormInfoPushRedis(RoutePayforminfoConfig routePayforminfoConfig,CommonResponse retval){ 7 //根據formId查詢出對應dto集合(商戶路由數據結構)(route_payforminfo_config+ROUTE_MGROUP_CONFIG) 8 List<PayFormInfoAndGroupConfigDto> list = this.getList(routePayforminfoConfig.getFormId(),routePayforminfoConfig.getStatus()); 9 // JSONArray json = JSONArray.fromObject(list); 10 Map<String,Object> map = new HashMap<String,Object>(); 11 List<String> keyList = new ArrayList<String>(); 12 if(CollectionUtils.isNotEmpty(list)){ 13 //遍歷獲取的list集合 14 for (PayFormInfoAndGroupConfigDto dto : list) { 15 if(StringUtils.isBlank(dto.getTranstype())){ 16 retval.setResult(false); 17 retval.setMessage("平臺號爲:"+dto.getFormid()+"時,查詢的對應商戶路由數據中存在交易類型爲空的數據,沒法拼接成合格的key,沒法推送或刪除緩存!!!"); 18 return retval; 19 } 20 //商戶路由數據結構key 21 String routePayforminfoConfigKey = "pc_"+dto.getFormid()+"_"+dto.getTranstype(); 22 System.out.println("原:key:"+routePayforminfoConfigKey+",value:"+redisUtils.getMap("route_payforminfo_config", routePayforminfoConfigKey)); 23 keyList.add(routePayforminfoConfigKey); 24 // map.put(routePayforminfoConfigKey, JSON.toJSONString(dto)); 25 //每個dto根據key的不一樣存入不一樣的list集合,相同的key存入相同list集合 26 if(map.containsKey(routePayforminfoConfigKey)){//若map中已經存入該key和對應的list 27 List<PayFormInfoAndGroupConfigDto> dtoList = (List<PayFormInfoAndGroupConfigDto>) map.get(routePayforminfoConfigKey); 28 dtoList.add(dto); 29 map.put(routePayforminfoConfigKey, JSONArray.fromObject(dtoList)); 30 }else{ 31 List<PayFormInfoAndGroupConfigDto> dtoList = new ArrayList<>(); 32 dtoList.add(dto); 33 map.put(routePayforminfoConfigKey, JSONArray.fromObject(dtoList)); 34 } 35 } 36 if("01".equals(routePayforminfoConfig.getStatus())){//若爲禁用,則刪除對應的緩存 37 for (String key : keyList) { 38 redisUtils.delMap("route_payforminfo_config",key); 39 //判斷商戶路由數據結構key是否存在 40 if(redisUtils.isExists("route_payforminfo_config",key)){ 41 retval.setResult(false); 42 retval.setMessage("刪除該緩存失敗,key爲:route_payforminfo_config+"+key+"!!!"); 43 return retval; 44 } 45 } 46 }else if("00".equals(routePayforminfoConfig.getStatus()) ){//狀態可用,推送緩存 47 //遍歷map:把map的value(JSONArray)都轉換爲String類型 48 for (String key : map.keySet()) { 49 map.put(key, map.get(key).toString()); 50 } 51 redisUtils.setMap("route_payforminfo_config", map); 52 }else{ 53 retval.setResult(false); 54 retval.setMessage("平臺商戶交易信息狀態有誤,沒法推送緩存!!!"); 55 return retval; 56 } 57 for (String key : keyList) { 58 System.out.println("Now:key:"+key+",value:"+redisUtils.getMap("route_payforminfo_config", key)); 59 } 60 61 }else{ 62 retval.setResult(false); 63 retval.setMessage("平臺號爲:"+routePayforminfoConfig.getFormId()+",狀態:"+routePayforminfoConfig.getStatus()+"時,未查詢到對應商戶路由緩存數據,沒法推送或刪除緩存!!!"); 64 return retval; 65 } 66 return retval; 67 }
7、出現問題:模糊刪除緩存時常常出現斷開鏈接的狀況:
1 route_payforminfo_config:原:key:pc_000000000009364_0001,value:[{"channelid":"48392900","core_trans_type":"0001","depth_match":"2","formid":"000000000009364","max_amt":"","min_amt":"","sort":"0","transtype":"0001"}] 2 route_payforminfo_config:原:key:pc_000000000009364_0002,value:[{"channelid":"48392900","core_trans_type":"0002","depth_match":"0","formid":"000000000009364","max_amt":"","min_amt":"","sort":"0","transtype":"0002"}] 3 route_payforminfo_config:原:key:pc_000000000009364_0003,value:[{"channelid":"48392900","core_trans_type":"0003","depth_match":"0","formid":"000000000009364","max_amt":"","min_amt":"","sort":"0","transtype":"0003"}] 4 route_payforminfo_config:原:key:pc_000000000009364_0004,value:[{"channelid":"48392900","core_trans_type":"0004","depth_match":"2","formid":"000000000009364","max_amt":"","min_amt":"","sort":"0","transtype":"0004"}] 5 route_payforminfo_config:原:key:pc_000000000009364_0005,value:[{"channelid":"48392900","core_trans_type":"0005","depth_match":"2","formid":"000000000009364","max_amt":"","min_amt":"","sort":"0","transtype":"0005"}] 6 route_payforminfo_config:原:key:pc_000000000009364_0013,value:[{"channelid":"48392900","core_trans_type":"0013","depth_match":"2","formid":"000000000009364","max_amt":"","min_amt":"","sort":"0","transtype":"0013"}] 7 route_payforminfo_config:原:key:pc_000000000009364_0014,value:[{"channelid":"48392900","core_trans_type":"0014","depth_match":"2","formid":"000000000009364","max_amt":"","min_amt":"","sort":"0","transtype":"0014"}] 8 route_payforminfo_config:原:key:pc_000000000009364_0016,value:[{"channelid":"48392900","core_trans_type":"0016","depth_match":"2","formid":"000000000009364","max_amt":"","min_amt":"","sort":"0","transtype":"0016"}] 9 route_payforminfo_config:原:key:pc_000000000009364_0022,value:[{"channelid":"48392901","core_trans_type":"0022","depth_match":"2","formid":"000000000009364","max_amt":"","min_amt":"","sort":"0","transtype":"0022"}] 10 route_payforminfo_config:原:key:pc_000000000009364_0203,value:[{"channelid":"48392901","core_trans_type":"0203","depth_match":"2","formid":"000000000009364","max_amt":"","min_amt":"","sort":"0","transtype":"0203"}] 11 route_payforminfo_config:原:key:pc_000000000009364_0301,value:[{"channelid":"48392900","core_trans_type":"0301","depth_match":"2","formid":"000000000009364","max_amt":"","min_amt":"","sort":"0","transtype":"0301"}] 12 route_payforminfo_config:原:key:pc_000000000009364_0302,value:[{"channelid":"00000088","core_trans_type":"0302","depth_match":"2","formid":"000000000009364","max_amt":"","min_amt":"","sort":"0","transtype":"0302"}] 13 刪除route_payforminfo_config:pc_000000000009364_0022:[{"channelid":"48392901","core_trans_type":"0022","depth_match":"2","formid":"000000000009364","max_amt":"","min_amt":"","sort":"0","transtype":"0022"}] 14 刪除route_payforminfo_config:pc_000000000009364_0302:[{"channelid":"00000088","core_trans_type":"0302","depth_match":"2","formid":"000000000009364","max_amt":"","min_amt":"","sort":"0","transtype":"0302"}] 15 刪除route_payforminfo_config:pc_000000000009364_0005:[{"channelid":"48392900","core_trans_type":"0005","depth_match":"2","formid":"000000000009364","max_amt":"","min_amt":"","sort":"0","transtype":"0005"}] 16 [kkLazy] 2019-02-26 11:09:45,246 [kklazy.launder.controller.AdController 27]-[ERROR] java.net.SocketException: Socket closed 17 redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketException: Socket closed 18 at redis.clients.util.RedisInputStream.ensureFill(RedisInputStream.java:202) 19 at redis.clients.util.RedisInputStream.readByte(RedisInputStream.java:40) 20 at redis.clients.jedis.Protocol.process(Protocol.java:151) 21 at redis.clients.jedis.Protocol.read(Protocol.java:215) 22 at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:340) 23 at redis.clients.jedis.Connection.getRawObjectMultiBulkReply(Connection.java:285) 24 at redis.clients.jedis.Connection.getObjectMultiBulkReply(Connection.java:291) 25 at redis.clients.jedis.BinaryJedis.hscan(BinaryJedis.java:3390) 26 at org.springframework.data.redis.connection.jedis.JedisConnection$5.doScan(JedisConnection.java:3338) 27 at org.springframework.data.redis.core.KeyBoundCursor.doScan(KeyBoundCursor.java:39) 28 at org.springframework.data.redis.core.ScanCursor.scan(ScanCursor.java:86) 29 at org.springframework.data.redis.core.ScanCursor.hasNext(ScanCursor.java:169) 30 at org.springframework.data.redis.core.ConvertingCursor.hasNext(ConvertingCursor.java:56) 31 at kklazy.utils.RedisUtils.deleteMapByMapPrex(RedisUtils.java:108) 32 at kklazy.acqinstmanagement.service.BaseMerchantCheckService.payFormInfoPushRedis(BaseMerchantCheckService.java:273) 33 at kklazy.acqinstmanagement.service.BaseMerchantCheckService.executeAuditOperate(BaseMerchantCheckService.java:183) 34 at kklazy.acqinstmanagement.service.BaseMerchantCheckService$$FastClassBySpringCGLIB$$9422d54f.invoke(<generated>) 35 at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) 36 at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:708) 37 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) 38 at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98) 39 at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262) 40 at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95) 41 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 42 at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:644) 43 at kklazy.acqinstmanagement.service.BaseMerchantCheckService$$EnhancerBySpringCGLIB$$57411bc.executeAuditOperate(<generated>) 44 at kklazy.acqinstmanagement.controller.BaseMerchantApproveController.commithandler(BaseMerchantApproveController.java:570) 45 at kklazy.acqinstmanagement.controller.BaseMerchantApproveController.commithandler(BaseMerchantApproveController.java:1) 46 at kklazy.persistence.controller.DefaultController.commit(DefaultController.java:263) 47 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 48 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 49 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 50 at java.lang.reflect.Method.invoke(Method.java:498) 51 at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215) 52 at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132) 53 at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104) 54 at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:749) 55 at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:689) 56 at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83) 57 at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938) 58 at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870) 59 at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961) 60 at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863) 61 at javax.servlet.http.HttpServlet.service(HttpServlet.java:707) 62 at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837) 63 at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) 64 at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:821) 65 at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1685) 66 at kklazy.security.filter.ReplaceFilter.doFilterInternal(ReplaceFilter.java:34) 67 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 68 at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1668) 69 at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88) 70 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 71 at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1668) 72 at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 73 at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118) 74 at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84) 75 at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 76 at kklazy.security.filter.SecurityFilter.doFilter(SecurityFilter.java:66) 77 at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 78 at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113) 79 at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 80 at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103) 81 at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 82 at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113) 83 at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 84 at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:146) 85 at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 86 at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154) 87 at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 88 at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45) 89 at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 90 at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199) 91 at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 92 at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110) 93 at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 94 at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50) 95 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 96 at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 97 at org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:125) 98 at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 99 at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87) 100 at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 101 at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192) 102 at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160) 103 at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344) 104 at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261) 105 at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1668) 106 at org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.doFilterInternal(OpenEntityManagerInViewFilter.java:177) 107 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 108 at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1668) 109 at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:581) 110 at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) 111 at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548) 112 at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:226) 113 at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1158) 114 at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:511) 115 at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185) 116 at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1090) 117 at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) 118 at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:119) 119 at org.eclipse.jetty.server.Server.handle(Server.java:517) 120 at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:308) 121 at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:242) 122 at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:261) 123 at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:95) 124 at org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:75) 125 at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceAndRun(ExecuteProduceConsume.java:213) 126 at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:147) 127 at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:654) 128 at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:572) 129 at java.lang.Thread.run(Thread.java:748) 130 Caused by: java.net.SocketException: Socket closed 131 at java.net.SocketInputStream.socketRead0(Native Method) 132 at java.net.SocketInputStream.socketRead(SocketInputStream.java:116) 133 at java.net.SocketInputStream.read(SocketInputStream.java:171) 134 at java.net.SocketInputStream.read(SocketInputStream.java:141) 135 at java.net.SocketInputStream.read(SocketInputStream.java:127) 136 at redis.clients.util.RedisInputStream.ensureFill(RedisInputStream.java:196) 137 ... 111 more
java.net.SocketException: Socket is closed,
該異常在客戶端和服務器都可能發生。異常的緣由是己方主動關閉了鏈接後(調用了Socket的close方法)再對網絡鏈接進行讀寫操做。
[kkLazy] 2019-02-26 15:34:10,398 [kklazy.launder.controller.AdController 27]-[ERROR] [B cannot be cast to java.util.List java.lang.ClassCastException: [B cannot be cast to java.util.List at redis.clients.jedis.Connection.getRawObjectMultiBulkReply(Connection.java:285) at redis.clients.jedis.Connection.getObjectMultiBulkReply(Connection.java:291) at redis.clients.jedis.BinaryJedis.hscan(BinaryJedis.java:3390) at org.springframework.data.redis.connection.jedis.JedisConnection$5.doScan(JedisConnection.java:3338) at org.springframework.data.redis.core.KeyBoundCursor.doScan(KeyBoundCursor.java:39) at org.springframework.data.redis.core.ScanCursor.scan(ScanCursor.java:86) at org.springframework.data.redis.core.ScanCursor.hasNext(ScanCursor.java:169) at org.springframework.data.redis.core.ConvertingCursor.hasNext(ConvertingCursor.java:56) at kklazy.utils.RedisUtils.deleteMapByMapPrex(RedisUtils.java:108) at kklazy.acqinstmanagement.service.BaseMerchantCheckService.payFormInfoPushRedis(BaseMerchantCheckService.java:273) at kklazy.acqinstmanagement.service.BaseMerchantCheckService.executeAuditOperate(BaseMerchantCheckService.java:183) at kklazy.acqinstmanagement.service.BaseMerchantCheckService$$FastClassBySpringCGLIB$$9422d54f.invoke(<generated>) at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:708) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:644) at kklazy.acqinstmanagement.service.BaseMerchantCheckService$$EnhancerBySpringCGLIB$$f900bfa3.executeAuditOperate(<generated>) at kklazy.acqinstmanagement.controller.BaseMerchantApproveController.commithandler(BaseMerchantApproveController.java:570) at kklazy.acqinstmanagement.controller.BaseMerchantApproveController.commithandler(BaseMerchantApproveController.java:1) at kklazy.persistence.controller.DefaultController.commit(DefaultController.java:263) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:749) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:689) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961) at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863) at javax.servlet.http.HttpServlet.service(HttpServlet.java:707) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837) at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:821) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1685) at kklazy.security.filter.ReplaceFilter.doFilterInternal(ReplaceFilter.java:34) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1668) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1668) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118) at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at kklazy.security.filter.SecurityFilter.doFilter(SecurityFilter.java:66) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:146) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:125) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192) at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160) at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344) at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1668) at org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.doFilterInternal(OpenEntityManagerInViewFilter.java:177) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1668) at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:581) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548) at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:226) at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1158) at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:511) at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185) at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1090) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:119) at org.eclipse.jetty.server.Server.handle(Server.java:517) at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:308) at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:242) at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:261) at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:95) at org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:75) at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceAndRun(ExecuteProduceConsume.java:213) at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:147) at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:654) at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:572) at java.lang.Thread.run(Thread.java:748)
緣由:多個線程同時調用了同一個jedis對象,致使內存數據被多個線程競爭,產生數據混亂。
也有說法是:初步懷疑是當前的connection讀了部分數據到本地內存中,而後讀超時後,並無把這個connection對應的本地內存數據清空或者destory掉這個connection(有可能直接將該connection正常地return到pool裏面了,而不是returnBrokenResource()),而後當前線程或者其餘線程繼續就用這個connection去作其餘的操做,就會致使下次讀取來的數據前面還夾雜着上次操做的數據,致使jedis內部沒法正確解析成指望的類型。
查看jedis源碼發現他的connection中對網絡輸出流作了一個封裝,其中自建了一個buffer,因此當發生異常的時候,這個buffer裏還殘存着上次沒有發送或者發送不完整的命令,這個時候沒有作處理,直接將該鏈接返回到鏈接池,那麼重用該鏈接執行下次命令的時候,就會將上次沒有發送的命令一塊兒發送過去,因此纔會出現上面的錯誤「返回值類型不對」; 因此正確的寫法應該是在發送異常的時候,銷燬這個鏈接,不能再重用!