- 浏览: 639574 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
liuche20083736:
非常好
从问题看本质: 研究TCP close_wait的内幕 -
xiaopohai85707:
优化算法与原来需求不符
过滤字符的性能调优?挤一挤还是有的 -
kmy_白衣:
生成的area图有时候 标签的数值和图标上看上去的数值不一致。 ...
OpenFlashChart2之恶心文档 -
tom&jerry:
大神,请教一个问题,按名称排序为何无效,用的2.4.3 XPA ...
深入浅出jackrabbit之十三 查询之AST和QT -
jd2bs:
改成精确匹配可以了< filter-mapping &g ...
细谈Ehcache页面缓存的使用
/**
*作者:张荣华(ahuaxuan)
*2007-06-28
*转载请注明出处及作者
*/
*作者:张荣华(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
>
作者:张荣华,未经作者同意不得随意转载!
评论
4 楼
罪恶的小手
2008-06-03
说实话还是有的没看懂,,
也许是我刚接触的问题吧,,
以后努力看吧,,
也许是我刚接触的问题吧,,
以后努力看吧,,
3 楼
xufei0110
2008-05-28
喜欢这样的 文章
在 java方面我还是一个初学者
虽然也能用 Struts Spring Hibernate 等
但 还没有能力 读懂 其源代码
不过 以后会加油的
在 java方面我还是一个初学者
虽然也能用 Struts Spring Hibernate 等
但 还没有能力 读懂 其源代码
不过 以后会加油的
2 楼
ahuaxuan
2007-07-24
annegu 写道
也就是说在使用spring+hibernate的时候,只读事务就是少一个flush对吧?
那使用spring+jdbc的时候,只读事务有哪些优化措施呢?是不是说就没有优化了呀,因为jdbc没有什么flush的说法呀。
那使用spring+jdbc的时候,只读事务有哪些优化措施呢?是不是说就没有优化了呀,因为jdbc没有什么flush的说法呀。
直接使用jdbc好像没有什么优化不优化之说,我不知道把connection设置为readonly到底能带来多少性能的提高,估计没有,而且很多jdbc驱动会忽略这选项,所以直接使用jdbc应该是没有什么特别的优化的
1 楼
annegu
2007-07-23
也就是说在使用spring+hibernate的时候,只读事务就是少一个flush对吧?
那使用spring+jdbc的时候,只读事务有哪些优化措施呢?是不是说就没有优化了呀,因为jdbc没有什么flush的说法呀。
那使用spring+jdbc的时候,只读事务有哪些优化措施呢?是不是说就没有优化了呀,因为jdbc没有什么flush的说法呀。
发表评论
-
过滤字符的性能调优?挤一挤还是有的
2010-05-29 05:54 3610/* *auth ... -
Master-Slave,Spring,Hibernate,故事曲折离奇,情结跌宕起伏
2009-02-05 13:49 8684/** *作者:张荣华 *日期 ... -
弃成见,反省,并重新认识struts.i18n.encoding
2008-12-24 15:42 3880[size=medium]之前和大家讨论了struts2.0中 ... -
关键字:查询,事务,粒度
2008-08-22 17:05 5137[size=medium]/** *作者: ... -
看看mina和memcached的联姻(适合不同语言客户端,高并发?)
2008-07-21 17:06 7984[size=medium]/** * 作者:张荣华 * 日 ... -
如何解决mysql的master-slave模式中ReplicationDriver的使用问题
2008-06-19 18:23 8220/** * 作者:张荣华 * 日期:2008-6-19 ... -
别装了,难道你们不想把properties直接注入到object中去(spring-plugin)?
2008-04-09 18:01 3651[size=small]/** *作者:张荣华(ahuaxu ... -
用jamon来监控你的sql执行效率
2008-02-25 15:48 3715/** *作者:张荣华 *日期:2008-2-25 ... -
java同msn的通信,大家想想用途吧
2007-11-24 17:14 2512程序员的生活真是单调,除了编程还是编程,工作日 ... -
EAI企业应用集成场景及解决方案
2007-09-21 18:21 3154/** *作者:张荣华(ahuaxuan) *2007-9 ... -
quartz和应用的集群问题
2007-08-21 18:36 12817之前看到很多关于quartz的讨论,尤其是关于quar ... -
优化程序之前,可用Jamon来监测你的Spring应用
2007-08-14 18:14 8125/** *作者:张荣华(ahuaxuan) *2007-8-1 ... -
请问责任链真的是一种设计模式吗
2007-07-26 18:12 9414坛子上讨论设计模式的也挺多的,但是关于这个责任链模式还没有人提 ... -
把ActiveMQ的控制台整合到你的web程序中
2007-07-19 12:06 8829在使用ActiveMQ的时候把ActiveMQ的控制台整 ... -
设计模式之:解剖观察者模式
2007-07-17 16:12 6866[size=9] 论坛上很多人都 ... -
java邮件:在简单和复杂之间的方案
2007-07-11 18:07 7584/** *作者:张荣华(ahuaxu ... -
强强连手, 在模板中分页,看Freemarker和displaytag的结合
2007-07-09 09:22 6925/** *作者:张荣华(ahuaxuan) *2007-0 ... -
让webwork零配置 第二章(实现)(实例已放出,大家可以下载运行)
2007-06-25 09:23 5707/** *作者:张荣华(ahuaxuan) *2007-0 ... -
让webwork2零配置,第一章(主贴再次更新)
2007-06-18 15:41 13379/** *作者:张荣华(ahuaxuan) *2007-0 ... -
Spring声明式事务管理源码解读之事务提交
2007-06-11 09:19 7285/** *作者:张荣华(ahuaxuan) *2007-0 ...
相关推荐
【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目...
【适合场景】:相关项目设计中,皆可应用在项目开发、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面中 可借鉴此优质项目实现复刻,也可基于此项目来扩展开发...
【适合场景】:相关项目设计中,皆可应用在项目开发、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面中 可借鉴此优质项目实现复刻,也可基于此项目来扩展开发...
【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目...
【适合场景】:相关项目设计中,皆可应用在项目开发、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面中 可借鉴此优质项目实现复刻,也可基于此项目来扩展开发...
【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目...
【适合场景】:相关项目设计中,皆可应用在项目开发、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面中 可借鉴此优质项目实现复刻,也可基于此项目来扩展开发...
【适合场景】:相关项目设计中,皆可应用在项目开发、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面中 可借鉴此优质项目实现复刻,也可基于此项目来扩展开发...
【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目...
【适合场景】:相关项目设计中,皆可应用在项目开发、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面中 可借鉴此优质项目实现复刻,也可基于此项目来扩展开发...
【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目...
【适合场景】:相关项目设计中,皆可应用在项目开发、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面中 可借鉴此优质项目实现复刻,也可基于此项目来扩展开发...
【适合场景】:相关项目设计中,皆可应用在项目开发、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面中 可借鉴此优质项目实现复刻,也可基于此项目来扩展开发...
【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目...
Spring 事务配置解惑.html 抓下来打包成了HTML文件, 方便离线观看
【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目...
【适合场景】:相关项目设计中,皆可应用在项目开发、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面中 可借鉴此优质项目实现复刻,也可基于此项目来扩展开发...
- **性能优化**:学习如何通过代码优化、并发编程等手段提高应用的性能。 #### 三、学习建议 - **持续实践**:理论与实践相结合,通过实际项目不断巩固所学知识。 - **社区参与**:加入.NET相关的开发者社区,如...
【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目...
《Java解惑》是一本由Google工程师编写的经典教材,旨在帮助开发者解决在实际编程过程中遇到的困惑和误解。这本书通过一系列精心设计的“Java谜题”,揭示了语言中的一些不直观特性和陷阱,从而提升读者对Java深层...