在什么情况下,MyBatis中的缓存会被清除?

参考回答

在 MyBatis 中,缓存的清除时机与 一级缓存二级缓存 相关,不同类型的缓存有不同的清除策略。具体而言,缓存会在以下几种情况下被清除:

一级缓存清除的情况:

  1. SqlSession 提交或回滚时
    • 提交commit())或者回滚rollback())时,一级缓存会被清除。
    • 这是因为缓存与当前 SqlSession 生命周期关联,提交或回滚操作意味着当前的事务结束,缓存也需要清空。
  2. SqlSession 关闭时
    • 一旦关闭 SqlSession,一级缓存会被清空。SqlSession 关闭时,所有与该 SqlSession 关联的缓存数据会丢失。
  3. 执行 insertupdatedelete 操作时
    • 这些操作会修改数据,为了避免缓存中的数据与数据库数据不一致,执行这些操作时,MyBatis 会清除当前 SqlSession 的一级缓存。

二级缓存清除的情况:

  1. insertupdatedelete 操作时
    • 当涉及到数据变更的操作(如插入、更新或删除数据)时,二级缓存中的相关数据会被清除。
    • 这是为了保证缓存中的数据与数据库的状态一致,避免使用过时的数据。
  2. 显式调用 clearCache() 方法
    • 在某些情况下,开发者可能希望手动清除二级缓存中的数据。MyBatis 提供了 clearCache() 方法,允许开发者显式清除指定 Mapper 中的缓存数据。
    • 例如,可以在 Mapper 的查询方法中调用 clearCache(),来清空缓存。
    <select id="selectUser" resultType="User">
       <!-- 查询用户数据 -->
    </select>
    
    <update id="updateUser">
       <!-- 更新用户数据 -->
    </update>
    
    <delete id="deleteUser">
       <!-- 删除用户数据 -->
    </delete>
    
    <clearCache />
    
    XML
  3. SqlSessioncommit()rollback()
    • 如果 SqlSession 提交或回滚事务时,所有缓存(包括一级缓存和二级缓存)都会被清除。
  4. 缓存失效策略
    • 如果使用外部缓存框架(如 EHCacheRedis 等),缓存会根据外部缓存的失效策略自动清除。例如,缓存可能设置了过期时间,当缓存数据过期时,会自动从缓存中清除。

详细讲解与拓展

1. 一级缓存清除的机制

一级缓存是与 SqlSession 生命周期绑定的,具有以下特点:
– 每个 SqlSession 会有独立的一级缓存,缓存的数据在 SqlSession 的生命周期内保持有效,直到 SqlSession 被提交、回滚或关闭。
– 当执行增、删、改操作时,MyBatis 会清空当前 SqlSession 的一级缓存。这样做是为了避免缓存中的数据与数据库中的数据不一致。
– 一级缓存是会话级别的,也就是说,它仅对当前的 SqlSession 有效。关闭 SqlSession 后,缓存会被清除,且缓存不能跨会话共享。

2. 二级缓存清除的机制

二级缓存是跨 SqlSession 的缓存,用于存储多个会话共享的数据。MyBatis 提供了清除二级缓存的机制,通常在以下几种情况下会清除:

  • 数据变更操作:对于增、删、改(insertupdatedelete)等操作,会影响数据库中的数据,为了保持缓存和数据库的数据一致,MyBatis 会清除相关的二级缓存数据。
    • 插入(Insert):当插入新数据时,涉及的数据项会被加入缓存。其他相关查询的缓存会失效,因此会清除二级缓存中的相关数据。
    • 更新(Update):更新操作会修改已有数据,为了保证缓存中的数据不与数据库中的数据不一致,相关的缓存数据会被清除。
    • 删除(Delete):删除操作会删除数据库中的数据,删除的记录对应的缓存也会被清除,以避免之后查询该记录时获取到过时的数据。
  • clearCache() 方法:如果在某些情况下你希望手动清空某个 Mapper 的二级缓存,可以调用 clearCache() 方法。这个方法会清除当前 SqlSession 中的缓存数据。

    例如:

    <update id="updateUser">
      <clearCache />
      <!-- 更新用户数据 -->
    </update>
    
    XML

    上述操作会在更新用户数据时清空缓存,确保后续的查询能获取到最新的数据。

  • 外部缓存框架的失效策略:如果你使用外部缓存框架(如 EHCacheRedis 等),缓存的清除会根据外部框架的缓存策略进行。例如,缓存可能会设置一个过期时间,当缓存项超过过期时间后自动清除。或者在数据更新时,外部缓存框架会根据特定的规则更新或删除缓存中的数据。

3. 缓存清除与缓存更新

除了清除缓存之外,MyBatis 也提供了缓存更新的机制:
– 对于二级缓存,可以在数据更新时直接更新缓存(如果使用了如 EHCacheRedis 等支持自动更新的缓存框架)。当数据变更时,不仅需要清除相关的缓存,还需要将更新后的数据重新写入缓存中,以保证后续查询能够从缓存中获取最新的数据。

4. 缓存策略

MyBatis 提供了一些基本的缓存清除策略,但开发者也可以根据应用的需求定义自己的缓存失效和清除策略。例如,可以配置缓存的 过期时间最大存储数量,这样可以在缓存达到一定条件时自动清除旧数据。使用外部缓存框架(如 EHCacheRedis)时,通常可以配置这些高级的缓存策略。

5. 二级缓存和事务

在 MyBatis 中,二级缓存的清除和事务紧密相关。当事务提交时,MyBatis 会根据提交的操作清除相关的缓存,保证缓存中存储的数据始终与数据库一致。若事务回滚,相关的缓存不会被清除,因为回滚意味着操作没有生效,缓存数据保持不变。

总结

MyBatis 中的缓存会在以下几种情况下被清除:
1. 一级缓存
SqlSession 提交、回滚或关闭时清除一级缓存。
– 执行 insertupdatedelete 操作时清除一级缓存。

  1. 二级缓存
    • 执行 insertupdatedelete 操作时,相关数据会被从二级缓存中清除。
    • 显式调用 clearCache() 方法清除指定 Mapper 的缓存。
    • 外部缓存框架(如 EHCacheRedis)根据缓存失效策略自动清除数据。

缓存的清除时机直接关系到数据的一致性和性能。在使用缓存时,合理地管理缓存的生命周期和清除策略,对于保证数据的准确性和提高系统性能至关重要。

发表评论

后才能评论