- 浏览: 421793 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (318)
- js (20)
- JQuery (2)
- Java (46)
- Oracle (4)
- mysql (21)
- ExtJs (17)
- Excel (2)
- Linux (8)
- Sql (8)
- Jsp (2)
- hibernate (12)
- jbpm (17)
- eclipse (8)
- 名博收藏 (1)
- Junit (2)
- 应用集成 (3)
- web (10)
- jboss (3)
- Rest (3)
- 其它 (7)
- 磁盘分区管理 (1)
- spring (18)
- SSO (4)
- tomcat (4)
- CSS (7)
- MemCached (6)
- EhCache (4)
- weblogic (1)
- apache (6)
- Exception design (1)
- db (1)
- 分析模式 (1)
- jstl (1)
- jsf (0)
- firefox (2)
- MongoDB (4)
- androidpn (1)
- hadoop (1)
- cvs (1)
- 微信公众号 (2)
- 高并发 (4)
- 技术论坛 (1)
- CDN (1)
- JVM (16)
- 加密 (4)
- maven (2)
- jenkins (1)
- hessian (1)
- 大数据处理 (2)
- NIO (0)
- netty (1)
- redis (1)
- git (1)
- Elastic Job (0)
最新评论
-
zgw06629:
或者<pre>aaaabbbbcccc</p ...
javaDoc注释换行 -
ddnzero:
...
StringBuffer换行 -
maosijun:
。。。。
EXT CExt.form.ComboBox选择一次后只剩一个选项 -
ysa198584:
你这有问题,当我的代码出现User.class的时候,反编绎的 ...
java的class文件批量反编译 -
dongj0325:
看到您的博客,很受启发,但还有关于jbpm4.4 timer使 ...
JBPM定时器(Timer)之Repeat属性不能使用变量
出自:http://www.iteye.com/topic/95124
**
*作者:张荣华(ahuaxuan)
*2007-06-28
*转载请注明出处及作者
*/
解惑:在spring+hibernate中,只读事务是如何被优化的。
大家都知道,spring+hibernate的环境下,spring对只读事务会有特别的优化,那么spring是如何做到这个优化的呢?
Without ejb中写到,当事务被标识为只读事务时,某些可以针对只读事务进行优化的资源就可以执行相应的优化措施,比如说hibernate的session在只读事务模式下不会尝试检测和同步持久对象的状态的更新。另外还写到jdbc的connection可以通过调用setReadOnly(true)来切换到只读事务模式上来;但是大多数jdbc driver会忽略掉他。
我们知道spring中所谓的只读事务就是通过设置session的flushmode为never来实现的(http://www.iteye.com/topic/87426 )。那么把flushmode设置为never能给我们带来什么呢?
我们来看一下hibernate中JDBCTransaction中的方法:
java 代码
- publicvoid commit() throws HibernateException {
- if (!begun) {
- thrownew TransactionException( "Transaction not successfully started" );
- }
- log.debug( "commit" );
- if ( !transactionContext.isFlushModeNever() && callback ) {
- transactionContext.managedFlush(); //if an exception occurs during flush, user must call rollback()
- }
- //也就是在这里会判断是否需要刷新一级缓存中的持久对象,如果session的flushmode不为//never而且需要回调的话,那么就刷新一级缓存中的持久对象,向数据库发送sql语句
- beforeTransactionCompletion();
- if ( callback ) {
- jdbcContext.beforeTransactionCompletion( this );
- }
- try {
- commitAndResetAutoCommit();
- //提交事务,并且把事务的commit方式设置为auto,是不是和spring在事务开始和事务结束//时设置session的flush mode的方式是一样的呀。
- log.debug( "committed JDBC Connection" );
- committed = true ;
- if ( callback ) {
- jdbcContext.afterTransactionCompletion( true , this );
- }
- afterTransactionCompletion( Status.STATUS_COMMITTED );
- }
- catch (SQLException e) {
- log.error( "JDBC commit failed" , e);
- commitFailed = true ;
- if ( callback ) {
- jdbcContext.afterTransactionCompletion( false , this );
- }
- afterTransactionCompletion( Status.STATUS_UNKNOWN );
- thrownew TransactionException( "JDBC commit failed" , e);
- }
- finally {
- closeIfRequired();
- }
- }
我们看一下那个managedFlush()方法,这个方法主要就是刷新一级缓存的一个方法:
java 代码
- public void managedFlush() {
- if ( isClosed() ) {
- log.trace( "skipping auto-flush due to session closed" );
- return ;
- }
- log.trace( "automatically flushing session" );
- flush();
- //刷新这个session实例的一级缓存。
- if ( childSessionsByEntityMode != null ) {
- Iterator iter = childSessionsByEntityMode.values().iterator();
- while ( iter.hasNext() ) {
- ( (Session) iter.next() ).flush();
- }
- } //刷新该session的子session的一级缓存。
- }
我们知道如果 session 的 flushmode 为 never 的时候,以上的方法是不会调用的,这样就可以省去很多 flush 的开销。于是命题就变成了 flush 操作有哪些开销了。
也许你要问 flush 和不 flush 有什么样的区别,在开销上有多大的区别呢。要看明白 hibernate 是怎么做 flush 的,那就必须要知道观察者模式了,实际上 session 是一个被观察者 (subject) ,而真正执行 flush 的是一个观察者 (observer), 我们来看一下下面这个图:
( 这个图是我画在纸上然后用手机拍下来的 )
从这里面我们可以看到 flush 实际上是由 DefaultFlushEventListener 来执行的,而且 sessionimpl 默认的只注册了一个 FlushEventListener 实例(为什么只有一个还要这样做,我估计他是为了扩展的需要,不知道 3.2 中是否就不止一个了呢?),这个 DefaultFlushEventListener 最终执行了 flush 的方法:
java 代码
- public void onFlush(FlushEvent event) throws HibernateException {
- final EventSource source = event.getSession();
- if ( source.getPersistenceContext().hasNonReadOnlyEntities() ) {
- flushEverythingToExecutions(event);
- //这个方法是flush前的准备工作,它把需要被flush的实体,集合,等等放到需要被flush
- //的一个队列中
- performExecutions(source);
- //这个方法是最重要的,因为在这里才是真正的执行sql语句,并且负责更新二级缓存(如果你//配置了二级缓存的话)
- postFlush(source);
- //负责flush后的善后工作,比如说一个对象不再被另外一个对象关联了,那么就把这个对象//从一级缓存重剔除,等等。
- if ( source.getFactory().getStatistics().isStatisticsEnabled() ) {
- source.getFactory().getStatisticsImplementor().flush();
- }
- }
- }
由此我们看到 hibernate 在执行 flush 操作的时候还是做了不少事情的,它不但要把持久对象刷到数据库,而且还要把其管理的对象也都刷到数据库中,这是一个很大的操作。同时如果你使用了二级缓存, flush 操作也会涉及到它,而且在 flush 时还要判断哪些时插入的,哪些是更新的,哪些是删除的等等, flush 完了还得更新一级缓存等。
其实我只是对 flush 作了最简单的概括和描述,事实上从代码上看来它远比我们想象的要来得复杂的多。
在对 flush 简单得了解了之后,我们再来讨论一下:为什么要把查询设置为只读事务。因为一个本来只是查询的操作,却要在事务提交时多做这么多事情,这显然是不合理的,所以 hibernate 才给 session 的设置了这么一个 flushmode ,那么只要这个 mode 为 never ,就可以免去这些不必要的操作。而 spring 在对 hibernate 的支持时也充分的考虑到了这一点,所以就把只读事务的 session 的 flush mode 设置为了 never 。这样我们事务提交时就不会执行 flush 操作了。
总结:
所以说,我们在使用 spring 时一定要注意把查询的操作定义成只读事务,这个可以给我们带来不必要的开销,比如看如下配置。
< property name = "transactionAttributes" >
< props >
< prop key = "do*" > PROPAGATION_REQUIRED prop >
< prop key = "get*" > PROPAGATION_REQUIRED,readOnly prop >
< prop key = "load*" > PROPAGATION_REQUIRED,readOnly prop >
< prop key = "find*" > PROPAGATION_REQUIRED,readOnly prop >
< prop key = "list*" > PROPAGATION_REQUIRED,readOnly prop >
props >
property >
或者事务的传播途径最好能设置为 supports (运行在当前的事务范围内,如果当前没有启动事务,那么就不在事务范围内运行)或者 not supports (不在事务范围内执行,如果当前启动了事务,那么挂起当前事务),也就是说查询操作其实可以不必要真正的开启一个数据库事务,因为开启一个真正的数据库事务又会给我们带来一点点可以忽略不计的开销。下面是一个例子
< property name = "transactionAttributes" >
< props >
< prop key = "do*" > PROPAGATION_REQUIRED prop >
< prop key = "get*" > PROPAGATION_SUPPORTS,readOnly prop >
< prop key = "load*" > PROPAGATION_SUPPORTS,readOnly prop >
< prop key = "find*" > PROPAGATION_SUPPORTS,readOnly prop >
< prop key = "list*" > PROPAGATION_SUPPORTS,readOnly prop >
props >
property >
发表评论
-
Spring Security认识
2015-07-28 15:29 589先来谈一谈Acegi的基础知识,Acegi的架构比较复杂,但 ... -
acegi第一个实例
2015-07-28 14:30 385目前acegi(Spring Security)主要是针对简 ... -
Acegi (Spring Security)入门
2015-07-28 13:25 936一、Acegi Security 介绍 1 ... -
Spring JMS MessageListener实现类不能参与事务拦截
2015-06-04 11:29 1372Spring JMS MessageListener实现类不 ... -
spring配置定时器的时间设置
2014-01-10 16:26 544转自:http://blog.csdn.net/zhaoz ... -
Spring跨库事务JOTM
2012-08-18 22:16 660http://sprone.iteye.com/blog/89 ... -
spring+hibernate+jotm分布式事务配置总结
2012-03-10 17:44 869在前段开拓的体系 中 ... -
用Spring集成的JOTM配置分布式事务
2012-03-10 17:38 1227【藏自】http://boy00fly.iteye.com ... -
spring分布式事务实现
2012-03-10 17:27 1069藏自:http://log-cd.iteye.com/blog ... -
Spring声明式事务管理源码解读之事务提交
2012-03-04 22:43 763其实我的感觉就是事务提交要比事务开始复杂,看事务是否提交我们还 ... -
【收藏】Spring TransactionManager和hibernate吐血经验谈
2011-08-22 20:45 1015http://lsk.iteye.com/blog/17879 ... -
【收藏】Spring事务王国架构
2011-08-20 10:12 645http://book.51cto.com/art/20090 ... -
【转载】TransactionSynchronizationManager理解
2011-08-19 21:25 909出自:http://blog.sina.com.cn/s/bl ... -
【收藏】主题:解惑 spring 嵌套事务
2011-08-18 23:08 697http://www.iteye.com/topic/3590 ... -
主题:Spring源码浅析 -- XML配置文件的载入与解析
2011-07-31 11:06 1073原文:http://www.iteye.com/topic/7 ... -
主题:Spring源代码解析(一):IOC容器
2011-07-31 08:45 776以下内容引自博客:http://jiwenke-spring. ... -
Spring MVC中的IoC容器初始化
2011-06-30 10:16 822http://blog.csdn.net/prince2270 ...
相关推荐
【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目...
【适合场景】:相关项目设计中,皆可应用在项目开发、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面中 可借鉴此优质项目实现复刻,也可基于此项目来扩展开发...
【适合场景】:相关项目设计中,皆可应用在项目开发、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面中 可借鉴此优质项目实现复刻,也可基于此项目来扩展开发...
【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目...
【适合场景】:相关项目设计中,皆可应用在项目开发、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面中 可借鉴此优质项目实现复刻,也可基于此项目来扩展开发...
【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目...
【适合场景】:相关项目设计中,皆可应用在项目开发、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面中 可借鉴此优质项目实现复刻,也可基于此项目来扩展开发...
【适合场景】:相关项目设计中,皆可应用在项目开发、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面中 可借鉴此优质项目实现复刻,也可基于此项目来扩展开发...
【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目...
Spring 事务配置解惑.html 抓下来打包成了HTML文件, 方便离线观看
【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目...
【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目...
【适合场景】:相关项目设计中,皆可应用在项目开发、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面中 可借鉴此优质项目实现复刻,也可基于此项目来扩展开发...
【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目...
【适合场景】:相关项目设计中,皆可应用在项目开发、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面中 可借鉴此优质项目实现复刻,也可基于此项目来扩展开发...
【适合场景】:相关项目设计中,皆可应用在项目开发、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面中 可借鉴此优质项目实现复刻,也可基于此项目来扩展开发...
【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目...
【适合场景】:相关项目设计中,皆可应用在项目开发、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面中 可借鉴此优质项目实现复刻,也可基于此项目来扩展开发...
【适合场景】:相关项目设计中,皆可应用在项目开发、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面中 可借鉴此优质项目实现复刻,也可基于此项目来扩展开发...
【适合场景】:相关项目设计中,皆可应用在项目开发、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面中 可借鉴此优质项目实现复刻,也可基于此项目来扩展开发...