List<ShopRebateCodePartner> rebateCodePartnerList = shopRebateCodePartnerDao.findEntityListByCond(cond, paginationInfo);
       if(rebateCodePartnerList == null || rebateCodePartnerList.size() == 0) {
           LoggerUtil.alarmInfo("[rebateCodePartner][紧急]找不到状态为未分发的合作方兑换码了!localRebateCode:" + localRebateCode);
           LoggerUtil.debug("[rebateCodePartner][紧急]找不到状态为未分发的合作方兑换码了!localRebateCode:" + localRebateCode);
           return null;
       }

       ShopRebateCodePartner result = null;

       while(result == null && rebateCodePartnerList != null && !rebateCodePartnerList.isEmpty()) {            
           for(ShopRebateCodePartner rebateCodePartner : rebateCodePartnerList) {            
              shopRebateCodePartnerDao.updateRebateCodePartnerNothing(rebateCodePartner.getRebateId());
               rebateCodePartner = shopRebateCodePartnerDao.findRebateCodePartnerByIdForUpdate(rebateCodePartner.getRebateId());
               if(rebateCodePartner.getStatus().equals(MovieConstant.REBATE_CODE_PARTNER_STATUS_UNUSE)) {
                   result  = rebateCodePartner;
                   break;
               }
           }
           if(result == null) {
               LoggerUtil.debug("find next,localRebateCode:" + localRebateCode);
               rebateCodePartnerList = shopRebateCodePartnerDao.findEntityListByCond(cond, paginationInfo);
           }
       }


之前遇到的问题是多线程跑这段程序时,某一个线程进入if(result==null)后查出来的list永远都是一样的,造成了死循环。

后来发现是由于mybatis的缓存造成的。

在mybatis框架中,在sqlSession未关闭之前,在一个session里面,如果执行相同的select语句,mybatis不会重新查询数据库,而是直接返回缓存在内存中的查询结果,这个是与myBatis的cache配置无关的,更改配置文件不起作用,要调用sqlSession.clearcache()函数才可以。

另外

  1. 映射语句文件中的所有 select 语句将会被缓存。

  2. 映射语句文件中的所有 insert,update delete 语句会刷新缓存。

所在上面代码中的update很重要,如果没有,就会出现一开始说的死循环,加上以后,就正常了。