hibernate缓存机制和事务隔离机制

一级缓存( Session缓存)

}         一级缓存的管理

?          应用程序调用Session的save()、update()、saveOrUpdate()、get()或load(),以及调用查询接口的 list()、iterate() 时,如果在Session缓存中还不存在相应的对象,Hibernate就会把该对象加入到第一级缓存中。

?          可以通过close/clear/evict清空缓存

}         作用

因为Session的生命期往往很短,存在于Session内部的第一级最快缓存的生命期当然也很短,所以第一级缓存的命中率是很低的。其对系统性能的改善也是很有限的。Session内部缓存的主要作用是保持Session内部数据状态同步。

二级缓存(SessionFactory缓存)

}         开启:

?          <property name="hibernate.cache.use_second_level_cache">true</property>

?          <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>

}         如何使用:

?          类定义前面:@cache,指该类的对象都会放入二级缓存。
@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)  //放入二级缓存中也可以被修改。一般用它。

}        
什么内容时候放入二级缓存:

?         
经常被访问、改动不频繁、数量有限。

}        
get/load会使用二级缓存。

}        
iterate也会使用二级缓存。

}        
list默认会往二级缓存中存放数据,即通过list查出的结果会放入二级缓存。但是list本身查询时不会使用二级缓存。

各种二级缓存插件

查询缓存

}        
查询缓存只对query.list()起作用

}        
查询缓存依赖于二级缓存,因此一定要打开二级缓存。

}        
查询缓存实现机制:以查询语句为key,查到的对象的id为value

}        
查询缓存的配置和使用:

?         
开启二级缓存

?         
<property
name="hibernate.cache.use_query_cache">true</property> //默认是fasle

?         
 在程序中必须手动启用查询缓存,如:query.setCacheable(true);

缓存算法问题

}        
缓存满了后,将内存中哪个对象清掉。

?         
LRU

?         
Least  Recently  
Used  最近最少被使用的。每个缓存对象都记录一个最后使用时间。

?         
LFU

?         
Least  Frequently 
Used  最近使用频率最少。

?         
FIFO

?         
First  In 
First Out

1+N问题

}        
在一对多/多对一中,经常出现1+N问题。

?         
在1方,查找得到了n个对象, 那么又需要将n个对象关联的集合取出,于是本来的一条sql查询变成了n+1条。

}        
解决方案:

?         
懒加载(延时加载、延迟加载)

?         
@OneToMany(mappedBy=“banji”,fetch=FetchType.LAZY)
(
默认即为此)

?         
二级缓存

?         
在对象更新,删除,添加相对于查询要少得多时, 二级缓存的应用将不怕n+1问题,因为即使第一次查询很慢,之后直接缓存命中也是很快的,刚好又利用了n+1。

List和iterator区别

}        
List仅仅会填充二级缓存,却不能利用二级缓存。

}        
iterator可以读二级缓存,对于一条查询语句,它会先从数据库中找出所有符合条件的记录的ID,再通过ID去缓存找,对于缓存中没有的记录,再构造语句从数据库中查出。在缓存中没有命中的话,效率较低。

}        
最好的办法就是:

?         
在应用启动时和数据被修改时使用list。平时则使用iterator。(只针对修改不频繁的数据!)

缓存机制的选用

}        
一般开始开发并不使用缓存机制。

}        
根据需求如果不能满足性能要求,才增加缓存。

?         
二级缓存:缓存数据内容变化频率不高的内容。

?         
查询缓存

}        
很多系统经常在应用层增加缓存:

?         
OSCACHE在J2EE中的应用

数据批量处理

}        
建议:

?         
大批量数据的处理不要使用hibernate,优先考虑JDBC的批量处理。(一般使用JDBC)

?         
如果对性能要求极高,可以考虑PL/SQL

事务隔离级别

}        
事务基本概念

}        
ACID即是atomicity(原子性),consistency(一致性),isolation(隔离性)和durability(执久性)的首字母的缩写

?         
原子性表示一个事务内的所有操作是一个整体,要 么全部成功,要么全失败;

?         
一致性表示一个事务内有一个操作失败时,所有的更改过的数据都必须回滚到修改前的状态;

?         
隔离性:事务查看数据时数据所处的状态,要么是另一并发事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看中间状态的数据。

?         
持久性事务完成之后,它对于系统的影响是永久性的。

}        
事务隔离级别从低到高:

?         
读取未提交(Read
Uncommitted)

?         
读取已提交(Read
Committed)

?         
可重复读(Repeatable
Read)

?         
序列化(serializable)

}        
读取未提交(Read
Uncommitted)

?         
这是最低的事务隔离级别,读事务不会阻塞读事务和写事务,写事务也不会阻塞读事务,但是会阻塞写事务。

?         
写事务不阻塞读事务,可以读取未提交的数据,容易造成脏读

?         
脏读现象:

?         
脏读解决方案:

?         
如果在第一个事务提交前,任何其他事务不可读取其修改过的值,则可  以避免该问题。

?         
读取已提交(Read
Committed)

?         
写事务就会阻塞读事务和写事务但是读事务不会阻塞读事务和写事务。读事务不阻塞写事务,但是有可能造成不可重复(在同一个事务中,再次读取数据时【就是你的select操作】,所读取的数据,和第1次读取的数据,不一样了。查询的结果将是不确定的)。

?         
不可重复读解决方案:

?         
锁住已经查询出来的记录!不让其他事物进行写操作

?         
可重复读(Repeatable
Read)

?         
读事务会阻塞写事务但是读事务不会阻塞读事务写事务会阻塞写事务和读事务。

?         
读事务不阻塞读事务(针对的是记录而不是表),可能会造成幻读问题

?         
幻读解决方案:

?         
解决办法是锁表,不让产生幻读的记录插入或删除。

?         
不过,一般不要考虑幻读问题。

?         
序列化(serializable)

?         
此种隔离级别是最严格的隔离级别,如果设置成这个级别,那么就不会出现以上所有的问题(脏读,不可重复读,幻影读)

?         
性能极低,一般不用!

}        
我们一般采用读取已提交或者更低的事务隔离级别,配合各种并发访问控制策略来达到并发事务控制的目的。

}        
如何使用:

<!-- 制定事务隔离级别
:1,2,4,8。二进制中:0001, 0010,0100,1000。这样直接采用位运算即可。权限控制中经常采用二进制位运算-->

<property
name="hibernate.connection.isolation">2</property>

乐观锁和悲观锁

}        
乐观锁Optimistic
Locking

?         
顾名思义就是保持一种乐观的态度,我们认为系统中的事务并发更新不会很频繁,即使冲突了也没事,大不了重新再来一次。

?         
它的基本思想就是每次提交一个事务更新时,我们想看看要修改的东西从上次读取以后有没有被其它事务修改过,如果修改过,那么更新就会失败。

?         
常用实现方法:

?         
在我们的实体中增加一个版本控制字段,每次事务更新后就将版本(Version)字段:版本字段的值加1.

?         
在实体类中增加@Version,
private  int  version
;getset 即可。

}        
悲观锁Pessimistic
Locking

?         
基本思想就是每次一个事务读取某一条记录后,就会把这条记录锁住,这样其它的事务要想更新,必须等以前的事务提交或者回滚解除锁。

?         
悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)

乐观锁和悲观锁的比较:

}        
乐观锁:

?         
优势:并发性好,性能较高。

?         
缺点:用户体验不好,录入了半天,提交时被告知已经修改!

}

}        
悲观锁:

?         
优势:会锁住记录,一个用户修改完成前,其他用户不能操作该记录。

?         
缺点:并发性不好,性能不高。

}        
对于悲观锁是针对并发的可能性比较大,而一般在我们的应用中用乐观锁足以。

时间: 2024-10-13 01:40:29

hibernate缓存机制和事务隔离机制的相关文章

事务隔离机制_悲观锁_乐观锁

5. 事务并发处理 a) 事务的特性:ACID i.Atomicity 原子性 ii.Consistency 一致性 iii.Isolation 隔离性 iiii.Durability 持久性 b) 事务并发时可能出现的问题 i. 第一类丢失更新(Lost Update) 时间 取款事务A 存款事务B T1 开始事务   T2   开始事务 T3 查询账户余额为1000元   T4   查询账户余额为1000元 T5   汇入100元把余额改为1100元 T6   提交事务 T7 取出100元把

理解MySql事务隔离机制、锁以及各种锁协议

一直以来对数据库的事务隔离机制的理解总是停留在表面,其内容也是看一遍忘一边.这两天决定从原理上理解它,整理成自己的知识.查阅资料的过程中发现好多零碎的概念如果串起来足够写一本书,所以在这里给自己梳理一个脉络,具体的内容参考引文或在网上搜一下.由于平时接触最多的是MySQL,所以文章中某些部分是MySQL特有的特性,请读者注意. 数据库并发操作会引发的问题: 多个事务同时访问数据库时候,会发生下列5类问题,包括3类数据读问题(脏读,不可重复读,幻读),2类数据更新问题(第一类丢失更新,第二类丢失更

一文带你理解脏读,幻读,不可重复读与mysql的锁,事务隔离机制

首先说一下数据库事务的四大特性 1 ACID 事务的四大特性是ACID(不是"酸"....) (1) A:原子性(Atomicity) 原子性指的是事务要么完全执行,要么完全不执行. (2) C:一致性(Consistency) 事务完成时,数据必须处于一致的状态.若事务执行途中出错,会回滚到之前的事务没有执行前的状态,这样数据就处于一致的状态.若事务出错后没有回滚,部分修改的内容写入到了数据库中,这时数据就是不一致的状态. (3) I:隔离性(Isolation) 同时处理多个事务时

数据库的事务隔离机制

事务隔离级别:一个事务对数据库的修改与并行的另一个事务的隔离程度. 两个并发事务同时访问数据库表相同的行时,这些问题可以归结为5类: 3类数据读问题(脏读.不可重复读和幻象读) 2类数据更新问题(第一类丢失更新和第二类丢失更新). 1.幻读:事务T1读取一条指定where条件的语句,返回结果集.此时事务T2插入一行新记录,恰好满足T1的where条件.然后T1使用相同的条件再次查询,结果集中可以看到T2插入的记录,这条新纪录就是幻想. 2.不可重复读取:事务T1读取一行记录,紧接着事务T2修改了

SQL锁机制和事务隔离级别

摘自:http://www.cnblogs.com/haiyang1985/archive/2009/02/27/1399641.html 锁机制 NOLOCK和READPAST的区别. 1.       开启一个事务执行插入数据的操作. BEGIN TRAN t INSERT INTO Customer SELECT 'a','a' 2.       执行一条查询语句. SELECT * FROM Customer WITH (NOLOCK) 结果中显示"a"和"a&quo

事务隔离机制

数据库隔离机制,要看事务!!!(两个事务读到的数据不一致不能算脏读什么的,只能是同一个数据读到的不一致.或者你一个读取的事务插到人家正在update的事务中了就是脏读.) 先说几个并发时候容易出现的问题: 1.更新丢失 分为两类 第一类, 覆盖丢失  (最后提交的事务B会覆盖B事务执行过程中的别的事务进行的修改):比如一个链接是要去改name,load一个name1,age1两个数据出来,修改了之后,事务还没提交的时候,又来了一个链接,load了同样的一个name1,age1出去,等第一个请求事

Hibernate 再接触 事务隔离机制

事务:要么都要完成,一个不完成就要回滚. ACID 原子性 一致性 独立性 持久性 第一类丢失更新 第一类丢失更新 脏读(读了另外一个事务没有提交的数据) 不可重复读(在同一个事务里,对数据库里的值前后读取值不一样) 第二类丢失更新(不可重复读的特殊情况) 幻读/(插入/删除)(读的时候,插入一条数据前后不一致) repeatable read 给数据库加把锁 别的无法改这条记录 serial 安全级别最高 但是速度最慢 一般设置为2 read-committed 不设的话依赖于数据库 原文地址

oracle 事务 锁机制

本课内容属于Oracle高级课程范畴,内容略微偏向理论性,但是与数据库程序开发和管理.优化密切相关:另外本课的部分内容在前面章节已经涉及,请注意理论联系实际. 事务  事务(Transaction)从 通讯的角度看:是用户定义的数据库操作序列,这些操作要么全做.要么全不做,是不可分割的一个工作单元.事务控制语句称为TCL,一般包括Commit和Rollback. 事务不是程序,事务和程序分属两个概念.在RDBMS中,一个事务可以有一条SQL语句.一组SQL语句或者整个程序:一个应用程序又通常包含

Hibernate缓存管理

Hibernate缓存管理 ++YONG原创,转载请注明 1.    Cache简介: 缓存(Cache )是计算机领域非常通用的概念.它介于应用程序和永久性数据存储源(如硬盘上的文件或者数据库)之间,其作用是降低应用程序直接读写永久性数据存储源的频率,从而提高应用的运行性能.缓存中的数据是数据存储源中数据的拷贝,应用程序在运行时直接读写缓存中的数据,只在某些特定时刻按照缓存中的数据来同步更新数据存储源. 缓存的物理介质通常是内存,而永久性数据存储源的物理介质通常是硬盘或磁盘,应用程序读写内在的