缓存:
缓存其实就是一块内存,而我们知道变量、数组、集合都是可以存数据的内存,所以缓存可以是数组或集合。
session的缓存:
session是一个对象,它里面维护了一个集合,所以说session有缓存功能。
例如class Demo{
List list =new ArrayList();
}
在这里我的Demo类维护了一个集合,那么Demo类就有缓存功能了,缓存功能就是将数据保存到内存的功能。
session的内部结构:
session的内部结构其实是分为两块的,一块是缓存区,另一块是快照区,缓存区用于存放用户操作的数据,快照区负责把数据的最终结果同步到数据库,如下图
当我们查询数据库主得到一条数据的时候,查询的结果User对象session会自动在自己的集合中保存一份,即就是我们缓存区的数据,而session的快照区此时也将此数据备份了一份。
此时我们做一个修改操作:将User对象的name属性改成亲动励2,那么此时缓存区的数据也自动更新成了亲动励2
那么当执行clear方法时,他的功能是将缓存区的数据清空,所以执行clear方法之后缓存区没有数据了,那么在事务提交的时候session会自动比较缓存区和快照区的数据,如果数据一样没有发生变化,那么就直接提交不用修改数据库,但是如果发现快照区和缓存区的数据不一样,那么他就首先会把快照区的数据修改成和缓存区的数据一样,然后再将快照区的数据同步到数据库。所以执行clear方法之后再提交事务缓存区和快照区最后都是没有数据的,所以数据无法同步到数据库,即最终数据库里面的结果name还是亲动励,不是亲动励2.
那如果我们执行的是evict()方法而不是clear()方法,那么效果是差不多的,只不过evict方法清除的是缓存中指定的对象,而clear清除的是缓存中所有的数据。
如果执行的不是clear和evict方法,执行的是flush方法,该方法主要是比较快照区和缓存区的数据是否一致,那如果你不调用此方法,那么快照区和缓存区的数据默认是在我们事务提交的时候比较。缓存区的数据会和快照区同步,并且持久化到数据库。所以flush方法只是提前同步快照区和缓存区,并没有情况缓存区。