二级缓存中有一个属性为readOnly
官网的解释如下:
readOnly(只读)属性可以被设置为 true 或 false。
1.(true)只读的缓存会给所有调用者返回缓存对象的相同实例。 因此这些对象不能被修改。这就提供了可观的性能提升。
2.(false)而可读写的缓存会(通过序列化)返回缓存对象的拷贝。速度上会慢一些,但是更安全,因此默认值是 false。
按照我自己的理解
1.当readOnly=true时 ,提示缓存此时应该只是用来读取数据 不要修改数据, 若A在此时修改了从缓存中提取出的数据会使得缓存中存取的数据也被修改,B在这时读取数据就会读取出被A修改后的错误数据。
2.当readOnly=false时, A修改了从缓存中提取出的数据并不会改变缓存中存储的原数据,B此时读取的就不会是错误的数据,这就确保了数据的安全。
下面是代码运行的结果展示:
设置readOnly=true时
@Test
// 二级缓存测试 1
public void testCacheLevel2() {
// 得到 session对象
final SqlSession session1 = factory.openSession();
final SqlSession session2 = factory.openSession();
// 得到 mapper 对象 (dao)
final UserMapper mapper1 = session1.getMapper(UserMapper.class);
final UserMapper mapper2 = session2.getMapper(UserMapper.class);
final User user = mapper1.selectById(1);
System.out.println(user);
// 关闭 session 1
session1.close();
System.out.println("before session query =============");
//从缓存中获取数据赋给user2
final User user2 = mapper2.selectById(1);
//改变username
user2.setUsername("shit2");
System.out.println("user2 " + user2);
System.out.println("user" + user );
System.out.println(user == user2);
// 关闭
session2.close();
}
结果:可以看到当改变姓名(王五)为(shit2)后,user对象中的姓名属性也改变为了(shit2)。
设置readOnly=false时
结果:可以看到当改变姓名(王五)为(shit2)后,user对象中的姓名属性并没有发生改变依然为(王五)。
可以理解为改变的对象仅是缓存中的一个拷贝,并没有改变缓存中存储数据的原对象。