性能优化(1+N,list与iterator,缓存,事务)
1、注意session.clear()的运用,尤其是不断分页循环的时候
A 在一个大集合中进行遍历,取出其中含有敏感字的对象
B 另一种形式的内存泄露.
2、1+N问题
问题描述:如@ManyToOne时,两个类分别是User与Group,取User时,本想发一条SQL语句,结果顺带发了N条语句,将每个User对应的Group也查询了。
解决方法有三种:
(1)设为@ManyToOne(fetch=FetchType.LAZY)
(2)在Group类中的@Entity下面加一条@BatchSize(size=5),则每一条SQL语句可以取出5个Group对象
(3)查询语句写为“from User u left join fetch u.group g”
3、list和iterator的区别
(1)list()返回List,直接取对象;list第二次发出,仍会到数据库中查询数据
(2)iterator先取对象的主键,即ID,等到要用的时候再根据ID取出对象;iterator第二次首先查找session级缓存.
4、缓存
(1)一级缓存(session级别的缓存)
例如,同一个session中,load两次,只向数据库发一条SQL语句。但如果是两个不同session中,分别load一次,则发两条SQL语句。
(2)二级缓存(SessionFactory级别的缓存,可以跨越session级别存在)
两个不同session中,分别load一次,要想只发一条SQL语句,则需要利用二级缓存。
load默认使用二级缓存,iterator默认使用二级缓存
list默认向二级缓存添加数据,但是查询的时候不使用.
如果Query需要使用二级缓存,则打开查询缓存。
适用情况:经常被访问,改动不大,数量有限的情况,如用户权限,组织机构等。
使用方法:Hibernate不提供二级缓存的实现,由其他厂商提供(如EH,OS,Swarm,JBoss)。使用时要配置xml,导入jar包。
在相关类中需要@Entity@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
(3)查询缓存:在二级缓存设置有效时才可以使用,需要在xml中设置。相同的查询语句才能使用查询缓存。
需要调用Query setCachable(true)方法指明使用二级缓存.
5、缓存算法
LRU,LFU, FIFO
Least Recently Used 按时间
Least Frequently Userd 按命中次数
First In First Out
memoryStoreEvictionPlicy=”LRU”(ehcache)
6、事务并发
(1)ACID 原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。
(2)事物并发带来的问题:
- 脏读:读了其他未提交事务B的数据,该事务B后来被回滚了
- 不可重复读:同一事务中,读了两遍,前后数据不一致。因为其他事务B更改了数据
- 幻读:同一事务中,读了两遍,前后数据不一致。因为其他事务B插入/删除了数据
- 第一类丢失更新(lost update): 在完全未隔离事务的情况下,两个事物更新同一条数据资源,某一事物异常终止,回滚造成第一个完成的更新也同时丢失。
- 第二类丢失更新(second lost updates):是不可重复读的特殊情况,如果两个事务都读取同一行,然后两个都进行写操作,并提交,第一个事务所做的改变就会丢失。
(3)数据库事务隔离级别:(javax.sql.Connection),事务隔离级别由数据库实现,Hibernate配置文件中可以对其进行配置。
- READ_UNCOMMITTED:允许读取改变了的还未提交的数据,可能导致脏读、不可重复读和幻读。
- READ COMMITTED(Oracle默认):允许并发事务提交之后读取,可以避免脏读,可能导致重复读和幻读。
- REPEATABLE_READ(MySQL默认):对相同字段的多次读取结果一致,可导致幻读。
- SERIALIZABLE:完全服从ACID的原则,确保不发生脏读、不可重复读和幻读。
(4)解决事物并发带来的问题采用悲观锁或乐观锁
a.悲观锁:依赖于数据库。
悲观锁,正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)。
一个典型的依赖数据库的悲观锁调用:select * from account where name=”Erica” for update这条 sql 语句锁定了 account 表中所有符合检索条件( name=”Erica” )的记录。本次事务提交之前(事务提交时会释放事务过程中的锁),外界无法修改这些记录。悲观锁,也是基于数据库的锁机制实现。
在Hibernate使用悲观锁十分容易,但实际应用中悲观锁是很少被使用的,因为它大大限制了并发性。如下例子:
T1,T2时刻取款事务和转账事务分别开启,T3事务查询ACCOUNTS表的数据并用悲观锁锁定,T4转账事务也要查询同一条数据,数据库发现该记录已经被前一个事务使用悲观锁锁定了,然后让转账事务等待直到取款事务提交。T6时刻取款事务提交,T7时刻转账事务获取数据。
b.乐观锁:与数据库无关,效率高。在类中加入private int version;属性@Version 该属性由Hibernate控制,每更新一次加1,不一致时报错。
相对悲观锁而言,乐观锁机制采取了更加宽松的加锁机制。悲观锁大多数情况下依靠数据库的锁机制实现,以保证操作最大程度的独占性。但随之而来的就是数据库性能的大量开销,特别是对长事务而言,这样的开销往往无法承受。乐观锁机制在一定程度上解决了这个问题。乐观锁,大多是基于数据版本(Version)记录机制实现。何谓数据版本?即为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是通过为数据库表增加一个"version"字段来实现。
乐观锁的工作原理:读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。此时,将提交数据的版本数据与数据库表对应记录的当前版本信息进行比对,如果提交的数据版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据。
Hibernate为乐观锁提供了3中实现:1. 基于version 2. 基于timestamp 3. 为遗留项目添加添加乐观锁
性能优化(1+N,list与iterator,缓存,事务)的更多相关文章
- Unity3D性能优化小tips——把this.transform缓存缓存起来
Unity3D开发时中有一个小tips,这在官方的文档里其实有提及的,但不那么显眼,这里小说一下: 在MonoBehaviour进行编程时,我们经常会用this.transform, this.gam ...
- Spark性能优化(2)——广播变量、本地缓存目录、RDD操作、数据倾斜
广播变量 背景 一般Task大小超过10K时(Spark官方建议是20K),需要考虑使用广播变量进行优化.大表小表Join,小表使用广播的方式,减少Join操作. 参考:Spark广播变量与累加器 L ...
- 性能优化(一个)Hibernate 使用缓存(一个、两、查询)提高系统性能
在hibernate有三种类型的高速缓存,我们使用最频繁.分别缓存.缓存和查询缓存.下面我们使用这三个缓存中的项目和分析的优点和缺点. 缓存它的作用在于提高性能系统性能,介于应用系统与数据库之间而存在 ...
- PLSQL_性能优化系列20_Oracle Result Cash结果缓存
20150528 Created By BaoXinjian
- 秋色园QBlog技术原理解析:性能优化篇:缓存总有失效时,构造持续的缓存方案(十四)
转载自:http://www.cyqdata.com/qblog/article-detail-38993 文章回顾: 1: 秋色园QBlog技术原理解析:开篇:整体认识(一) --介绍整体文件夹和文 ...
- web性能优化——简介
简介 性能优化的第一准则:加缓存.几乎绝大部分优化都围绕这个来进行的.让用户最快的看到结果. 性能优化的第二准则:最小原则.绝不提供多余的信息.比如,静态资源(图片.css.js)压缩,图片的滚动加载 ...
- 性能优化之Java(Android)代码优化
最新最准确内容建议直接访问原文:性能优化之Java(Android)代码优化 本文为Android性能优化的第三篇——Java(Android)代码优化.主要介绍Java代码中性能优化方式及网络优化, ...
- 之前做web性能优化的一些个人心得
一个web项目后期的维护主要在于性能方面.数据吞吐量一旦增大各种bug都出来了.那些通过硬件<数据库分表,数据库主从分离,读写分离>等的一些手段此处就不多说了.本文主要在编码方面做一个性能 ...
- .NET程序性能优化基本要领
想了解更多关于新的编译器的信息,可以访问 .NET Compiler Platform ("Roslyn") 基本要领 在对.NET 进行性能调优以及开发具有良好响应性的应 ...
- Object-C知识点 (四) 性能优化
#pragma mark - 性能优化 1. 行高一定要缓存 缓存行高是解决性能优化的最佳途径(除非刷新频率已经很高了,否则一定要缓存)2. 尽量减少计算,所有需要素材提前计算好3. 控件不要设置圆角 ...
随机推荐
- Linux C/C++基础 文件(下)
1.fgets和fputs #include <stdio.h> int fputs(const char * str, FILE * stream); 功能:将str所指定的字符串写入到 ...
- hadoop的单机配置
hadoop的单机配置 准备工作 利用vim /etc/sysconfig/network命令修改主机名称. Ssh security shell 远程登录 登录远程服务器 $ ssh user@ho ...
- 学习shell的第一天
1.命令历史 作用:查之前使用的命令 关于命令历史的文件 每个用户家目录下面的 .bash_history 在关机的时候,会自动写入一次 (history -a 将内存中的命令历史写入文件) ...
- python 爬虫小案例
爬取百度贴吧帖子信息 #!/usr/bin/env python # -*- coding: utf-8 -*- # author: imcati import requests,re,time cl ...
- 【STM32】串行通信原理
(1)通信接口背景知识 并行通信: --传输原理:数据各个位同时传输 --优点:速度快 --缺点:占用引脚资源多 串行通信: ...
- 【0.3】mysql复制的日常管理维护,mysql复制常见问题处理
[1]复制的日常管理 #复制的日常管理与维护 [1.1]show slave status\G :在从库查看从库线程状态 [1.2]flush tables with read lock; :主从不 ...
- 小菜鸟之Oracle数据库之事务
Oracle数据库之事务 1. 什么是事务 在数据库中事务是工作的逻辑单元,一个事务是由一个或多个完成一组的相关行为的SQL语句组成,通过事务机制确保这一组SQL语句所作的操作要么都成功执行,完成整个 ...
- typescript中新增的基本数据类型
javascript中有7种数据类型,分别是:boolean,number,string,null,undefined和object,以及在es6中新增的一种类型 symbol.而typescript ...
- MFC多线程的创建使用
最近学习了MFC多线程的使用, 写了一个继承CWinThread类的类MyThread: 在头文件开头用#define定义一个线程函数入口地址(会在下面定义代码中写出) 在类的开头加上IMPLEMEN ...
- AppCan IDE中有时格式化代码后,代码就运行不了了。
AppCan IDE中有时格式化代码后,代码就运行不了了.