最近在了解mybatis缓存的时候, 看到了一级缓存, 并且默认是打开的,但是我有一个疑惑:
如有两个SqlSession, 假设叫做a,b; 如果a查询一次, 紧接着b更新一次, 然后此时a再次查询,是不是查询到的还是老数据
所以是不是我对SqlSession理解不到位? 如果两个用户并发在接口上请求, 是不是大概率不在一个SqlSession上? 如果是, 那会不会出现脏读问题?
最近在了解mybatis缓存的时候, 看到了一级缓存, 并且默认是打开的,但是我有一个疑惑:
如有两个SqlSession, 假设叫做a,b; 如果a查询一次, 紧接着b更新一次, 然后此时a再次查询,是不是查询到的还是老数据
所以是不是我对SqlSession理解不到位? 如果两个用户并发在接口上请求, 是不是大概率不在一个SqlSession上? 如果是, 那会不会出现脏读问题?
你的理解基本是对的,MyBatis 确实有一级缓存,并且默认是打开的。这是全局的 SqlSession 级别的缓存。对于你的问题,确实可能会有数据一致性的问题。
让我们详细分析一下你的情况:
假设 a 查询了数据并将其存储在它的 SqlSession 的一级缓存中,然后 b 更新了数据并提交到数据库。这时,如果 a 再次查询相同的数据,由于它的 SqlSession 的一级缓存中仍然保存着旧的数据,所以它无法获取到 b 已经更新过的数据。因此,确实可能会出现数据不一致的情况。
解决此问题的一种方式是使用 MyBatis 的二级缓存。二级缓存是跨 SqlSession 的,它可以避免这种数据不一致的情况。你可以在映射文件中开启二级缓存:
<cache/>
当然,脏读问题一般来说只会在一个数据库事务内发生,不同的事务之间不会出现脏读问题。也就是说,如果两个用户并发在接口上请求,他们各自的事务内获取的数据都是一致的,不会相互影响。但是,如果在同一事务内(例如,使用相同的 SqlSession),那么确实可能会出现脏读问题。这通常发生在读取(SELECT)和写入(UPDATE, DELETE, INSERT)操作同时发生时。
15 回答8.4k 阅读
8 回答6.2k 阅读
1 回答4.1k 阅读✓ 已解决
3 回答2.2k 阅读✓ 已解决
2 回答3.1k 阅读
2 回答3.8k 阅读
3 回答1.7k 阅读✓ 已解决
是,这个叫‘可重复读’。
不是大概率不在,是不可能在(除非真的自己写了一套奇怪的逻辑,多个请求能访问到同一个 session…),所以也不存在脏读
通常来说,每个请求独享一个数据库连接,一个 sql session,一个事务上下文