MyBatis 一级二级和自定义缓存

2020-12-18 From 程序之心 By 丁仪

缓存是 MyBatis 的重要功能。使用缓存可以减低数据库查询次数,对性能有较大的提升。MyBatis 提供了一级缓存和二级缓存,但是可能存在脏数据问题,使用时需要谨慎评估。如有需要可以自定义缓存来规避脏数据问题。

一级缓存

一级缓存主要用于在一次数据库会话中多次执行查询条件完全相同的 SQL 语句,MyBatis 会优先命中一级缓存降低对数据库的直接查询次数,一级缓存的最大生效范围是 SqlSession 内部。一级缓存默认是开启的。

MyBatis 中 SqlSession 持有 Executor,每个 Executor 都有 LocalCache。在一次会话中,如果有修改数据的 SQL,比如执行了 update 语句,一级缓存默认会失效。

MyBatis 根据查询语句生成 MappedStatement,首先在 LocalCache 中进行查询,如果命中就直接返回;如果没有命中,才去查询数据库,并把查询到的数据结果写入 LocalCache。一级缓存 LocalCache 实际上是使用 HashMap 实现的。

开启一级缓存的配置方式是设置 setting。value 可选值是 SESSION 和 STATEMENT,默认是 SESSION。

二级缓存

如果需要在多个 SqlSession 之间共享缓存,则需要使用二级缓存。二级缓存默认关闭,需要手动配置开启。开启二级缓存后,会使用 CachingExecutor 装饰 Executor,在进入一级缓存的查询流程前,先在 CachingExecutor 进行二级缓存的查询。二级缓存的 POJO 对象必须可以序列化,需要实现 Serializable 接口。

同一个 namespace 下的所有操作语句,都影响着同一个 Cache。开启二级缓存后,所有 select 语句会被缓存,可以设置 useCache="false" 实现每次都访问 db 数据;insert、update、delete 语句会刷新缓存,可以设置 flushCache="false" 实现不刷新缓存。

开启二级缓存的配置方式是设置 cache 标签。cache 标签有如下配置项:

eviction:回收策略,可选 FIFO(先进先出)、LRU(最近最少使用)、SOFT(软引用)、WEAK(弱引用),默认是 LRU;

flushInterval:缓存刷新时间(可以理解为超时时间),单位是毫秒,不配置则只有执行 SQL 时刷新;

size:缓存对象个数上限,默认 1024;

readOnly:是否只读,默认可读可写,也就是对缓存对象(实际是副本)的修改是安全的;

blocking:若缓存无法命中,是否会一直 blocking 直到有对应的数据进入缓存;

在多表查询时,namspace 无法感知其他 namspace 对涉及的表的数据修改,因此可能会引起脏数据。在有需要的情况下,可以使用 cache ref 来引用其他 namspace 的缓存配置,实现两个 namspace 共用相同的缓存,但是缓存的粒度会变粗,数据操作都会对缓存有影响。

在事务中,事务提交后才会对缓存有影响,事务回滚或者不提交不会对缓存有影响。

自定义缓存

前面的缓存都是本地缓存,在大型分布式系统中无法保证全局的一致性。可以使用 MyBatis 的自定义缓存能力进行扩展,把数据缓存在 Redis 或其他流行的缓存服务器中,来解决数据一致性问题。自定义缓存时,需要我们自己解决缓存的写入、读取、清除等功能。

自定义缓存需要实现 org.apache.ibatis.cache.Cache 接口,然后在 cache 标签中配置,属性是 type="你的缓存对象类型"。Cache 接口定义了 putObject、getObject、removeObject、clear、getSize、getReadWriteLock 几个方法,能够实现缓存数据的写入、查询、删除、计数等功能。

如果自定义缓存需要初始化参数,也可以在内使用进行配置。MyBatis 可以通过 setter 方法把配置参数传给实现类,完成实现类自定义的初始化。

总结

  • 一级缓存在 SqlSession 内部共享,二级缓存可以跨越多个 SqlSession;
  • 二级缓存可以管控到 namespace 级别,但是多表查询时,可能会出现脏数据;
  • 本地缓存在有数据更新时才会失效,因此分布式情况下无法保证缓存同时失效,可能会出现脏数据;
  • 单机应用或数据一致性要求不高时,设置合理的缓存有效期可以保证业务需求;
  • 分布式应用,可以使用自定义分布式缓存来解决数据一致性问题;

本文来源:程序之心,转载请注明出处!

君子曰:学不可以已。
《分布式算法精髓》
互联网是一个分布式系统,无线通信、云计算或并行计算、多核系统、移动网络也是如此。蚁群、大脑甚至人类社会都可以被建模为分布式系统。本书强调这些分布式系统中共同涉及的主题和技术,特别是强调分布式系统设计中的一些基本问题,涵盖通信、协调、容错性、本地性、并行性、打破对称性、同步化、不确定性等。
发表感想

© 2016 - 2024 chengxuzhixin.com All Rights Reserved.

浙ICP备2021034854号-1    浙公网安备 33011002016107号