Ibatis缓存应用的一个小问题

 

最近在做执法系统重构功能的开发,发现Ibatis的缓存一个应用的问题,跟大家分享一下。
使用过Ibatis缓存的同事可能也会遇到过这个问题。
背景:
    接过项目经理的一个案件转办的任务,功能大概是这样的,一个表单的新增、修改(新增、修改都只需要修改关联表的数据,主表数据是不需要用的)等,然后就提交审核,功能完成,提交给测试组。很简单吧。
    第二天,MT跟我说:“怎么你的转办功能这样子的呀???都保存不了数据。”然后我又回来测了下,没发现问题,郁闷中……。再回来找找问题,后来发现原来是在不同的环境下体现出来的效果不同,在开发环境下是可以正常读到数据,但在IIS下就读不到数据。在网上找一下,没找到解决方法,怎么办,又郁闷中……。后来跑去问土华,土华给了我一个很有很好的提示:是Ibatis缓存的问题,具体问题出在哪里,再找找咯。然后我就跟着这个思路去找,找找找……。终于找到了,爽呀!真的是Ibatis缓存问题。
数据表设计:
看代码,了解下数据表的结构和数据读取
主表(CaseSummary)
<?xml version="1.0" encoding="utf-8" ?>
<sqlMap namespace="CaseSummary" xmlns="http://ibatis.apache.org/mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <!--别名-->
  <alias>
    <typeAlias alias="CaseSummary" type="Comit.TE.Web.Domain.Cases.CaseSummary, Comit.TE.Web.Domain" />
  </alias>
  <!--缓存模型-->
  <cacheModels>
    <cacheModel id="CaseSummaryCache" implementation="MEMORY">
      <flushInterval hours="24"/>
      <flushOnExecute statement="CaseSummary.AddCaseSummary"/>
      <flushOnExecute statement="CaseSummary.UpdateCaseSummary"/>
      <flushOnExecute statement="CaseSummary.DeleteCaseSummary"/>
      <flushOnExecute statement="CaseSummary.DeleteCaseSummarys"/>
      <flushOnExecute statement="CaseSummary.UpdateCaseSummaryName"/>
      <property name="Type" value="WEAK"/>
    </cacheModel>
  </cacheModels>
  <!--字段映射-->
  <resultMaps>
    <resultMap id="CaseSummaryResult" class="CaseSummary">
      <result property="Id" column="ID" />
      <result property="Code" column="CODE" />
      <result property="File" column="FILE" />
      <result property="Name" column="NAME" />
      <result property="Administration" column="ADMINISTRATION" />
      <result property="Category" column="CATEGORY" />
      <result property="Subject" column="SUBJECT" />
      <result property="Items" column="ITEMS" />
      <result property="Time" column="TIME" />
      <result property="Address" column="ADDRESS" />
      <result property="Income" column="INCOME" />
      <result property="Created" column="CREATED" />
      <result property="Creater" column="CREATER" />
      <result property="Organization" column="ORGANIZATION" />
      <result property="Amerce" column="AMERCE" />
      <result property="Status" column="STATUS" />
      <result property="Description" column="DESCRIPTION" />
      <result property="Road" column="ROAD" />
      <result property="PileStart" column="PILE_START" />
      <result property="PileEnd" column="PILE_END" />
<result property="Propertys" column="ID" select="CaseProperty.GetPropertysBySummaryID" />
      <result property="PunishType" column="PUNISH_TYPE" />
    </resultMap>
  </resultMaps>
  <statements>
    <!--获取多条-->
<select id="GetCaseSummarys" resultMap="CaseSummaryResult" parameterClass="CaseSummary" cacheModel="CaseSummaryCache">
      select "ID", CODE, "FILE", "NAME", ADMINISTRATION, "CATEGORY", SUBJECT, ITEMS, "TIME", ADDRESS, INCOME, CREATED, CREATER, "ORGANIZATION",AMERCE, STATUS, DESCRIPTION, ROAD, PILE_START, PILE_END, PUNISH_TYPE
      from T_CASE_SUMMARY
      where 1=1
      <include refid="WhrClauseEqual" />
    </select>
  </statements>
</sqlMap>
关联表(CaseProperty)
<?xml version="1.0" encoding="utf-8" ?>
<sqlMap namespace="CaseProperty" xmlns="http://ibatis.apache.org/mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <!--别名-->
  <alias>
    <typeAlias alias="CaseProperty" type="Comit.TE.Web.Domain.Cases.CaseProperty, Comit.TE.Web.Domain" />
  </alias>
  <!--缓存模型-->
  <cacheModels>
    <cacheModel id="CasePropertyCache" implementation="MEMORY">
      <flushInterval hours="24"/>
      <flushOnExecute statement="CaseProperty.AddCaseProperty"/>
      <flushOnExecute statement="CaseProperty.UpdateCaseProperty"/>
      <flushOnExecute statement="CaseProperty.DeleteCaseProperty"/>
      <flushOnExecute statement="CaseProperty.DeleteCasePropertys"/>
      <flushOnExecute statement="CaseProperty.DeleteCasePropertyBySummary"/>
      <property name="Type" value="WEAK"/>
    </cacheModel>
  </cacheModels>
  <!--字段映射-->
  <resultMaps>
    <resultMap id="CasePropertyResult" class="CaseProperty">
      <result property="Id" column="ID" />
      <result property="Summary" column="SUMMARY" />
      <result property="Name" column="NAME" />
      <result property="Value" column="VALUE" />
      <result property="Shift" column="SHIFT" />
    </resultMap>
  </resultMaps>
  <statements>
    <!--根据主表ID获取信息-->
<select id="GetPropertysBySummaryID" resultMap="CasePropertyResult" parameterClass="int" cacheModel="CasePropertyCache">
      select ID, SUMMARY, NAME, VALUE, SHIFT
      from T_CASE_PROPERTY
      where SUMMARY=$SUMMARY$
    </select>
  </statements>
</sqlMap>

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public ActionResult Edits( string code)  
         {
  
             try
             { //读取(在IIS下读取数据是有问题的,只能读取到上一次的缓存数据,取不到最新的数据)
                 caseSummary = CaseSummaryService.GetCaseSummarys(HttpContext, new CaseSummary() { Code = code }).FirstOrDefault();  
  
         }
             catch (Exception e)
             {
                 HandleException(Response, e);
             }
             return Json(caseSummary, JsonRequestBehavior.AllowGet);
         }
  
public ActionResult Edits([ModelBinder( typeof (JsonBinder<CaseProperty>))]List<CaseProperty> propertys)
         {
             try
             {
  
                 CasePropertyService.UpdateCaseProperty(HttpContext, propertys); //对表单修改,只修改关联表(已经对property的数据进行更新了,但还是取不到数据)
  
             }
             catch (Exception e)
             {
                 HandleException(Response, e);
             }
             return Json( true );
         }

问题就出在“只修改关联表”,这样一来Ibatis把propertys的物理数据表和Ibatis缓存同时更新。在代码执行“GetCaseSummarys“时,读到propertys的是缓存数据是并不是最新的。实际上,此时propertys的缓存数据是有两个版本,要拿到最新的数据有两种方法:
1.修改读取的方法,直接调用“Getpropertys”读取property表的数据;
2.修改更新的方法,先调用“UpdateCaseSummary”把主表的缓存版本更新,再执行“GetCaseSummarys”;
      小结,一个小实验来证明得来,Ibatis的缓存在VS的调试环境下没起到缓存的做用,在IIS下程序就能真正起到数据缓存的作用,并且同一个数据对象可能会存在多个版本的缓存数据。如果有哪位同事用到Ibatis缓存机制来优化系统的性能,那就要留意缓存的问题。在VS调用下看到的效果并不是真实的效果。小提醒:你看到的并不一定是你所想的,小心被VS给忽悠了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值