如何理解mybatis的一级缓存?会不会造成数据不一致的问题?

最近在了解mybatis缓存的时候, 看到了一级缓存, 并且默认是打开的,但是我有一个疑惑:

如有两个SqlSession, 假设叫做a,b; 如果a查询一次, 紧接着b更新一次, 然后此时a再次查询,是不是查询到的还是老数据

所以是不是我对SqlSession理解不到位? 如果两个用户并发在接口上请求, 是不是大概率不在一个SqlSession上? 如果是, 那会不会出现脏读问题?

阅读 1.4k
avatarAI BotBETA

你的理解基本是对的,MyBatis 确实有一级缓存,并且默认是打开的。这是全局的 SqlSession 级别的缓存。对于你的问题,确实可能会有数据一致性的问题。

让我们详细分析一下你的情况:

  • 当你查询数据时,MyBatis 会首先尝试从一级缓存中获取数据,如果找不到,才会去数据库中查询。
  • 当你有两个 SqlSession,a 和 b,他们对同一数据进行操作时,可能会出现数据不一致的情况。

假设 a 查询了数据并将其存储在它的 SqlSession 的一级缓存中,然后 b 更新了数据并提交到数据库。这时,如果 a 再次查询相同的数据,由于它的 SqlSession 的一级缓存中仍然保存着旧的数据,所以它无法获取到 b 已经更新过的数据。因此,确实可能会出现数据不一致的情况。

解决此问题的一种方式是使用 MyBatis 的二级缓存。二级缓存是跨 SqlSession 的,它可以避免这种数据不一致的情况。你可以在映射文件中开启二级缓存:

<cache/>

当然,脏读问题一般来说只会在一个数据库事务内发生,不同的事务之间不会出现脏读问题。也就是说,如果两个用户并发在接口上请求,他们各自的事务内获取的数据都是一致的,不会相互影响。但是,如果在同一事务内(例如,使用相同的 SqlSession),那么确实可能会出现脏读问题。这通常发生在读取(SELECT)和写入(UPDATE, DELETE, INSERT)操作同时发生时。

1 个回答
如有两个SqlSession, 假设叫做a,b; 如果a查询一次, 紧接着b更新一次, 然后此时a再次查询,是不是查询到的还是老数据

是,这个叫‘可重复读’。

所以是不是我对SqlSession理解不到位? 如果两个用户并发在接口上请求, 是不是大概率不在一个SqlSession上? 如果是, 那会不会出现脏读问题?

不是大概率不在,是不可能在(除非真的自己写了一套奇怪的逻辑,多个请求能访问到同一个 session…),所以也不存在脏读

通常来说,每个请求独享一个数据库连接,一个 sql session,一个事务上下文

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题