HibernateTemplate通常是为了加快开发效率,还有就是使用Hibernate的时候,更简洁,更便利,而统一的声明事务,又让原本就已经很简洁的Hibernate对事务的处理,大大简化 但任何事务都有两面性,在带来大量便捷的同时,Hibernate也给咱们留下了一点小小的遗憾,好比众所周知的,在处理大批量数据查询的时候,Hibernate的查询效率,是不尽人意的,有人作过测试,在高并发查询的时候,hibernate的查询效率,仅仅至关于使用jdbc效率7成左右,这对于对速度有着很高要求的互联网应用来讲,不能不说是悲剧。 尽管有存在有各类各样的缓存解决方案,但仍是在高并发查询下,让人们对 hibernate的性能,捏了一把汗.同时,hibernate在查询的时候,所带来的n+1问题,也一直让人所诟病. 进而在批量操做方面,好比在早期,在没有使用jdbc3.0的batch update的时候,hibernate的批量删除,是让人很头痛的, 甚至是一条记录的删除,也不能作到像jdbc同样让人满意. 因此,在咱们的项目框架中,混合使用hibernate与jdbc,各自发挥各自的优点与长处,弥补对方的缺陷,提升系统的响应速度.可是须要注意的时, jdbcTemplate的HibernateTemplate混合使用的时候,要注意其混合事务的处理. 正如咱们之前的项目同样,一开始在项目中使用的是JDBCTemplate,为了提升开发效率决定采用Hibernate,可是发现Hibernate 在作批量操做时,效率不是很理想。 web
因此如今采用JDBCTemplate和Hibernate混用,这时有几个注意事项。 spring
1.若是采用JDBCTemplate的部分只涉及到查询,则可使用Hibernate的应用缓存,即二级缓存。 数据库
2.若是采用JDBCTemplate的部分涉及到对数据库的更新操做,即增,删,改.则不能开启Hibernate的二级缓存,若是系统有缓存的须要,我以为能够本身在逻辑层实现缓存.Java的缓存方案仍是不少的。 缓存
3.在使用Spring作为容器的系统中,混用JDBCTemplate和Hibernate,事务管理请统一使用HibernateTransactionManager,前提是JDBCTemplate和Hibernate共用一个DataSource. session
那么,咱们来看看共享事务管理如何配置。
在Spring和Hibernate的配置文件中,咱们能够对类中的方法进行事务控制,也就是说某个方法中含有多个数据库的写操做,咱们能够经过建立一个Spring中的HibernateTransactionManager实例,把相应的sessionFactory注入到其的sessionFactory属性中,由事务声明的方式进行事务控制。样例以下: 并发
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory"><ref bean="sessionFactory"/></property> </bean>
可是这种方式有个局限性,若是该方法中既有调用Hibernate进行存储,也有经过JdbcTemplate进行数据库的写操做,若是在方法执行过程当中,写数据发生异常时,只有归入了事务管理的经过Hibernate进行存储的数据才会回滚,而经过JdbcTemplate方式进行操做的数据不会进行回滚。缘由是Hibernate与JdbcTemplate使用的是不一样DBConnection,并且JdbcTemplate未申明相应的事务管理,因此要想在既使用了Hibernate,也使用了JdbcTemplate进行数据库存储操做的方法进行事务管理,须要在Spring的配置文件作适当的修改,样例以下: mvc
<bean id=" transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory"><ref bean="sessionFactory"/></property> <property name="dataSource"><ref bean="oaDataSource"/></property> </bean>
JdbcTemplate和Hibernate能被wrap到同一个事务里。成立须要几点条件: app
一、使用同一个datasource; 框架
二、事务交由HibernateTransactionManager管理; 高并发
三、相关dao以及service须要使用runtime exception体系,使用spring提供的exception能够,本身封装设计的runtime exception体系也行。
最后,提醒下,在须要事务处理的地方请注意不要写try-catch,必定要throw出来,事务就靠这个异常回滚呢。以上是以前作共享事务总结的,当时测试是基于Junit,测试经过。如今,项目中用到Flex+Spring,其中就运用了共享事务管理。可是我在使用的时候事务一直就是不生效,后面整了很久,发现了这么一篇文章《Spring3MVC+Mybatis3.1框架下的事务》http://my.oschina.net/xuqiang/blog/97633:
切面配置在了root applicationContext的bean上了,而spring mvc会根据xxx-servelt.xml生成一个本身的applicationContext,他的父applicationContext为root applicatonContext,当mvc有本身的bean时便再也不去向父context要bean,致使声明事务无效。
受到启发,个人问题与之相似,一样的,我也这么去作,最终成功了! 如下是加载flex配置,另外,在applicationContext-flex.xml下面将事务的配置写进去。
web.xml的配置: <!--========================加载flex配置========================--> <servlet> <servlet-name>flexDispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/classes/applicationContext-flex.xml</param-value> </init-param> <load-on-startup>2</load-on-startup> </servlet> applicationContext-flex.xml的配置: <!-- 使用annotation定义事务 --> <tx:annotation-driven transaction-manager="transactionManager" /> <!-- Hibernate 与spring jdbcTemplate共享事物的管理 --> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> <property name="dataSource" ref="dataSource"/> </bean>