dolphin icon indicating copy to clipboard operation
dolphin copied to clipboard

咨询一个关于mybaits cache的问题

Open csxuyang opened this issue 9 years ago • 1 comments

现有AMapper.xml中定义了对数据库表 ATable 的CRUD操作,BMapper定义了对数据库表BTable的CRUD操作; 假设 MyBatis 的二级缓存开启,并且 AMapper 中使用了二级缓存,AMapper对应的二级缓存为ACache; 除此之外,AMapper 中还定义了一个跟BTable有关的查询语句,类似如下所述: [html] view plaincopyprint?在CODE上查看代码片派生到我的代码片 <select id="selectATableWithJoin" resultMap="BaseResultMap" useCache="true">
select * from ATable left join BTable on ....

执行以下操作:

  1. 执行AMapper中的"selectATableWithJoin" 操作,此时会将查询到的结果放置到AMapper对应的二级缓存ACache中;
  2. 执行BMapper中对BTable的更新操作(update、delete、insert)后,BTable的数据更新;
  3. 再执行1完全相同的查询,这时候会直接从AMapper二级缓存ACache中取值,将ACache中的值直接返回;

好,问题就出现在第3步上: 由于AMapper的“selectATableWithJoin” 对应的SQL语句需要和BTable进行join查找,而在第 2 步BTable的数据已经更新了,但是第 3 步查询的值是第 1 步的缓存值,已经极有可能跟真实数据库结果不一样,即ACache中缓存数据过期了!

总结来看,就是: 对于某些使用了 join连接的查询,如果其关联的表数据发生了更新,join连接的查询由于先前缓存的原因,导致查询结果和真实数据不同步; 从MyBatis的角度来看,这个问题可以这样表述: 对于某些表执行了更新(update、delete、insert)操作后,如何去清空跟这些表有关联的查询语句所造成的缓存;

这种场景应该如何解决? 可能跟本插件无关,我只是想咨询一下,谢谢

csxuyang avatar Aug 27 '15 00:08 csxuyang

我认为最简单的方案应该是在第1步操作执行的语句定义中,使用flushCache=true的设置,强制L1和L2缓存清空:

<select
  id="selectPerson"
  parameterType="int"
  parameterMap="deprecated"
  resultType="hashmap"
  resultMap="personResultMap"
  flushCache="false"
  useCache="true"
  timeout="10000"
  fetchSize="256"
  statementType="PREPARED"
  resultSetType="FORWARD_ONLY">

其中: image

你可以试一下!:)

beihaifeiwu avatar Aug 27 '15 01:08 beihaifeiwu