Hibernate性能优化小解:
1. 注意session.clear()的运用,用完的数据要clear一下,及时让GC回收掉
2. 1+N问题
什么是1+N问题?
在对象关系中存在1对多或者多对一的情况,当一的这方设置 cascade={CascadeType.ALL} 或者fetch=FetchType.EAGER时。会出现当查询一 的这方的时候也会顺带的查询多的那一方。
第一种解决方案:设置fetch=FetchType.LAZY(在hibernate中如果一的这方不设 置,默认就是LAZY)
第二种解决方案:session.createCriteria(Class).list();
join fetch(HQL做表连接查询);
3. List与iterate的区别
⑴.List直接把对象取出来放到session缓存里。
iterate 先取出id,什么时候用到对象了再根据id去数据库中取出来。
⑵.List没有利用Session级的缓存,第二次利用仍然会发出sql语句去数据库里取 数据。
iterate利用Session级的缓存,第二次先找Session级的缓存。
4. 一级缓存和二级缓存和查询缓存
一级缓存:Session级别的缓存(Session中的HashMap)。
二级缓存:SessionFactory级别的缓存(依赖第三方jar包,适合放经常被访问,改 动不大,数量有限的对象)。
查询缓存:记录查询结果集,下次再重复查询时直接从缓存中拿(依赖于二级缓存, 要先打开二级缓存)。
5. 缓存算法(解决缓存满了之后怎么处理)
⑴.LRU(Least Recently Used) 最近很少被使用
⑵.LFU(Least Frequently Used)最不常被使用
⑶.FIFO (First In First Out) 先进先出
6. 事务的并发处理
什么是事务?事务的四种特性?(原子性,一致性,隔离性,持久性)
事务并发时可能出现的问题:
⑴.丢失更新:两个事务都
⑵.脏读:一个事务读取到了另外一个事务没有提交的数据
⑶.不可重复读:一个事务两次读取同一条数据,但是两次读取的
结果不一致。
⑷.幻读:一个事务读取过程之中,另外一个事务又插入了一条
新数据。
7. 数据库的事务隔离机制
⑴.read-uncommited : 能够去读取没有提交的数据
⑵.read-commited : 只能读取提交的数据(不能避免不可重复读)
⑶.repeatableread : 可重复读(加锁,一个事务没处理完别的事务不能修改)
⑷.serializable : 不能并发(效率最低)
8. Hibernate事务隔离
Haibeinate事务隔离也是和数据库事务隔离一样,也是四种。
设置hibernate的事务隔离级别:
hibernate.connection.isolation=2
1 :read-uncommited
2 :read-commited
4 :repeatableread (MySql默认)
8 :serializable
9. 悲观锁:(前提是为了考虑并发的效率,把Hibernate.connection.isolation=2,还要解 决不可重复读的问题)注意依赖于数据库的锁。
工作原理:就是把一个事务要操作的数据上锁,这个事务不释放锁别的事务不 能操作该数据
设置锁方式:
Session.load(XX.class,id,LockMode.UPGRADE);
10. 乐观锁:
一般是通过为数据库表增加一个version字段来实现
工作原理:读取数据时,将version字段一同读出,之后进行更新时version会加一。
所以在一个事务更新之前先检查version是否和当前的version一致,如果 不一致证明已经被别的事务修改过了。
11. 悲观锁和乐观锁的理解
悲观锁在对于取数据之前,不确定在操作期间会不会有人来修改我的数据,那么干 脆先上把锁,等我操作完别人再操作,而相对于乐观锁,想取数据就取,乐观的觉 得在我操作数据的期间不会有人来修改数据,就算我要修改数据时发现数据被更新 了(version字段不一致),大不了再重新处理一遍或者做出相应的处理就行了。所 以乐观锁相率比较高。