尽量一两句话把我理解的说明白,个人认为要先理解缓存
=================================================================
1、缓存(一级,二级)
缓存就是把对数据库的查询操作转移到查询内存,使用时先查询一级缓存,
如果一级缓存没有,查询二级缓存(如果启用),如果二级缓存没有,查询数据库,并将结果存入缓存。
缓存是一个map(键值对),键是主键jd,值是id对应的实体对象。
对于读相对于写频繁,常量,稳定基础数据等适合放入缓存。
一级缓存是Session级别的,若在同一个Session内进行了多次查询(get,load,或其他支持一级缓存的方法),
则只进行一次数据库查询,然后放入缓存,在之后查询同一条记录(id),查询一级缓存并得到结果。
二级缓存是SessionFactory级别的,因为一个应用程序只有一个SessionFactory,所以也是应用级别的,
因为一个应用程序只对应一个jvm进程,所以也是进程级别的。但在集群环境下,虽然各受管跑的是同一套应用程序,
但各受管的应用对应各自独立的jvm进程,所以各受管有自己的SessionFactory,二级缓存在同一个SessionFactory内跨Session,
但是每个SessionFactory有自己的二级缓存,所以二级缓存不是集群级别的。但是如果所使用的二级缓存支持分布式,
当二级缓存内数据变更时,会更新(或清理)其他受管上的缓存副本,这时各受管间的二级缓存保持同步,
达到了集群内跨进程的效果,但这是分布式缓存的作用,如果不支持分布式,二级缓存达不到这个效果。(这是个人理解)
由于二级缓存是SessionFactory级别的,所以其他非hibernate进行的数据操作,hibernate的二级缓存管理不了。
=================================================================
2、对象状态(临时态,持久态,游离态)
盗个图
重点是持久化状态,持久化对象就是已经被保存进数据库的实体对象,并且这个实体对象现在还处于Hibernate的缓存管理之中。
这时对该实体对象的任何修改,都会在清理缓存时同步到数据库中,而不论是否调用update方法。
由此可以看出,这个状态就是说哪些对象会被同步到数据库,who(持久化状态的对象)from(一级缓存)to(数据库)when( 清理缓存时)。
=================================================================
3、隔离级别(脏读,幻读,不可重复读)
a、脏读(两事务访问同一数据)
事务1:begin→data_before→update→data_after→commit
事务2:在事务1提交或回滚之前,事务1更新之后,读取data,读取到data_after,如果事务1成功提交,
并提交的正是data_after,则无影响。若事务2读取到data_after之后,事务1回滚,则读取到脏数据。
b、不可重复读(两事务访问同一数据)
事务1:begin→read 1→read 2→commit
事务2:在事务1第二次读取同一数据之前,第一次读取同一数据之后,对该数据进行修改,
事务1两次读取同一数据可能会不一样。
c、幻读(两事务访问同一搜索条件数据)
搜索条件condition
事务1:begin→更新满足condition的所有行数据→commit
事务2:在事务1提交之前,事务1更新完之后,事务2插入满足condition的数据,
此时事务1操作者发现自己并没有更新所有满足条件的数据,像幻觉一样。
补充 :基于元数据的 Spring 声明性事务
Isolation属性一共支持五种事务设置,具体介绍如下:
l DEFAULT 使用数据库设置的隔离级别 (默认),由 DBA 默认的设置来决定隔离级别
l READ_UNCOMMITTED 会出现脏读、不可重复读、幻读 (隔离级别最低,并发性能高)
l READ_COMMITTED 会出现不可重复读、幻读问题(锁定正在读取的行)
l REPEATABLE_READ 会出幻读(锁定所读取的所有行)
l SERIALIZABLE 保证所有的情况不会发生(锁表)
=================================================================
4、锁(hibernate悲观锁,乐观锁)
乐观锁(Optimistic Locking) 相对悲观锁而言,乐观锁机制采取了更加宽松的加锁机制。
悲观锁大多数情况下依靠数据库的锁机制实现,以保证操作最大程度的独占性。
但随之而来的就是数据库性能的大量开销,特别是对长事务而言,这样的开销往往无法承受。
而乐观锁机制在一定程度上解决了这个问题。乐观锁,大多是基于数据版本(Version)记录机制实现。
何谓数据版本?即为数据增加一个版本标识,在基于数据库表的版本解决方案中,
一般是通过为数据库表增加一个 “version” 字段来实现。读取出数据时,将此版本号一同读出,
之后更新时,对此版本号加一。此时,将提交数据的版本数据与数据库表对应记录的当前版本信息进行比对,
如果提交的数据版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据,不予更新。
=================================================================