当前位置:文档之家› S详细讲解SH中Spring事务流程

S详细讲解SH中Spring事务流程

给你详细讲一下SSH框架的事物管理,希望对你有帮助。

Struts+hibernate+spring整合开发web应用是相当流行的,只需要简单的配置就能轻松的对数据库进行crud操作,下面就hibernate+spring 的配置做一下剖析,一边与大家一起分享经验:1、准备工作:可以利用hibernate tools生成相关映射文件已经po对象、dao对象,dao 也可以自己手动编写,无非就是实现crud,如果通过继承hibernate提供的HibernateDaoSupport,则可以更轻松的实现关键就在于配置文件,下面看一个样例:<xml version="" encoding="utf-8"><beans xmlns=" "xmlns:xsi=" "xsi:schemaLocation=" "><!--配置数据源--><bean id="dataSource" class="" destroy-method="close"><!-- 指定连接数据库的驱动 --><property name="driverClass" value=""/><!-- 指定连接数据库的URL --><property name="jdbcUrl" value="jdbc:"/><!-- 指定连接数据库的用户名 --><property name="user" value="root"/><!-- 指定连接数据库的密码 --><property name="password" value="root"/><!-- 指定连接数据库连接池的最大连接数 --><property name="maxPoolSize" value="20"/><!-- 指定连接数据库连接池的最小连接数 --><property name="minPoolSize" value="1"/><!-- 指定连接数据库连接池的初始化连接数 --><property name="initialPoolSize" value="1"/><!-- 指定连接数据库连接池的连接的最大空闲时间 --> <property name="maxIdleTime" value="20"/></bean><!--配置数据库会话工厂--><bean id="sessionFactory" class=""><property name="dataSource" ref="dataSource"/> <property name="mappingResources"><list><value>com/ouya/ </list></property><property name="hibernateProperties"><props><prop key=""> <prop key="">true</prop><prop key="">true</prop></props></property></bean><!--配置事务管理器--><bean id="transactionManager" class=""><property name="sessionFactory"><reflocal="sessionFactory"/></property></bean><!—-配置Spring 事务管理器代理 --><bean id="transactionProxyFactory" abstract="true" lazy-init="true" class=""><property name="transactionManager"><ref local="transactionManager"/></property><property name="transactionAttributes"><props><prop key="save*">PROPAGATION_REQUIRED</prop><prop key="insert*">PROPAGATION_REQUIRED</prop> <prop key="del*">PROPAGATION_REQUIRED</prop><prop key="add*">PROPAGATION_REQUIRED</prop><prop key="update*">PROPAGATION_REQUIRED</prop> <propkey="find*">PROPAGATION_REQUIRED,readOnly</prop><propkey="search*">PROPAGATION_REQUIRED,readOnly</prop><propkey="remove*">PROPAGATION_REQUIRED,readOnly</prop><propkey="query*">PROPAGATION_REQUIRED,readOnly</prop><propkey="list*">PROPAGATION_REQUIRED,readOnly</prop><propkey="count*">PROPAGATION_REQUIRED,readOnly</prop><prop key="get*">PROPAGATION_REQUIRED,readOnly</prop> </props></property></bean><!-- Hibernate模板 --><bean id="hibernateTemplate" class=""><property name="sessionFactory"><ref local="sessionFactory" /></property></bean><!--服务层对象--><bean id="us" class=""><property name="userDao"><ref local="userDao"/></property></bean><!-- spring代理用户服务对象 --><bean id="userService" parent="transactionProxyFactory"><!-- 如果上面的服务层对象实现了接口,则此处必须设置proxyTargetClass为true,否则会报classcast异常 --><!--<property name="proxyTargetClass" value="true"/>--><property name="target" ref="us"/></bean><!-- 用户数据访问对象DATA ACCESS OBJECT --><bean id="userDao" class=""><property name="hibernateTemplate" ref="hibernateTemplate"/> </bean></beans>可以看到配置文件的步骤:1、配置数据源2、配置会话工厂(依赖注入上面的数据源,还要注入hbm映射文件[注意正确的位置]、hibernate属性文件)3、配置事务管理器(依赖注入上面的会话工厂)4、 Spring中声明事务管理器(根据需要又可分为几种,但都要依赖注入上面的事务管理器,此外还需要配置transationAttributes)后面的一些普通的bean配置就不用说了上面的例子中使用的声明事务管理器是:TransactionProxyFactoryBean,这样的话我们就需要在后面配置目标bean,比如上面的例子中我们的原服务对象是id为us的UserService(没有实现接口),所以我们为他配置了id为userService的代理对象(目标bean),程序中使用时只能通过使用代理对象才能实现数据库操作功能(代理对象的父类是上面声明的事务管理器,一边我们使用的时候开启事务),如果直接使用服务对象就无法开启事务程序中调用:UserService us = (UserService) ("userService");注:userService就是上面配置的代理对象的id,而不是原服务对象的id但是如果我们想通过原服务对象的id来使用对象,则我们需要使用代理事务管理器BeanNameAutoProxyCreator(根据beanname自动代理),上面的配置文件需要做改动,做两件事(当然先要删除原来配置的TransactionProxyFactoryBean,不然就混乱了,可能会报错的):1、增加一个事务拦截器<bean id="transactionInterceptor" class=""><property name="transactionManager"><ref local="transactionManager"/></property><property name="transactionAttributes"><props><prop key="save*">PROPAGATION_REQUIRED</prop><prop key="insert*">PROPAGATION_REQUIRED</prop><prop key="del*">PROPAGATION_REQUIRED</prop><prop key="add*">PROPAGATION_REQUIRED</prop><prop key="update*">PROPAGATION_REQUIRED</prop><propkey="find*">PROPAGATION_REQUIRED,readOnly</prop><propkey="search*">PROPAGATION_REQUIRED,readOnly</prop><propkey="remove*">PROPAGATION_REQUIRED,readOnly</prop><propkey="query*">PROPAGATION_REQUIRED,readOnly</prop><propkey="list*">PROPAGATION_REQUIRED,readOnly</prop><propkey="count*">PROPAGATION_REQUIRED,readOnly</prop><prop key="get*">PROPAGATION_REQUIRED,readOnly</prop> </props></property></bean>2、定义自动代理事务管理器<!-- 定义BeanNameAutoProxyCreator--><bean class=""><!-- 如果服务层对象是接口实现类,则需要设置proxyTargetClass属性为true --><!--<property name="proxyTargetClass" value="true"--><!-- 指定对满足哪些bean name的bean自动生成业务代理 --> <property name="beanNames"><!-- 下面是所有需要自动创建事务代理的bean--><list><value>us</value></list><!-- 此处可增加其他需要自动创建事务代理的bean--></property><!-- 下面定义BeanNameAutoProxyCreator所需的事务拦截器--><property name="interceptorNames"><list><!-- 此处可增加其他新的Interceptor --><value>transactionInterceptor</value></list></property></bean>然后我们在程序中调用时应如下:UserService us = (UserService) ("us");注:注意与上面使用TransactionProxyFactoryBean时的调用区别,此处我们用getbean时直接取原服务层对象的id,不需要去配置目标bea,这也正是BeanNameAutoProxyCreator(根据bean名称自动代理)的含义所在附录:1、关于hibernate的属性详解:<bean id="dataSource" class="" destroy-method="close"><!-- 以下配置都是使用属性文件中的配置,而之所以可以这样写,就是因为有属性占位符配置的原因 --><property name="driverClass" value="${}"/><property name="jdbcUrl" value="${}"/><property name="user" value="${}"/><property name="password" value="${}"/><!-- 连接池维持的最小的连接个数 --><property name="minPoolSize" value="5"/><!-- 连接池维持的最大的连接个数 --><property name="maxPoolSize" value="20"/><!-- 最大空闲时间, 当某个连接在这个时间内没活动后将从池中移除,前提是池中至少多于最少的连接数: minPoolSize --><property name="maxIdleTime" value="1800"/><!-- 为加强准备语句的执行性能,此参数指定被缓存的PreparedStatement 的个数 --><property name="maxStatements" value="50"/></bean>Hibernate 会话厂 SessionFactorySession 就是用于每次与数据库会话的,因此需要:数据库的配置参数,这些参数就是上面的数据源指定的! 因此我们只需引用即可: ref="dataSource";实体映射配置配置结果缓存配置(这里使用的是开源的 ehcache)<!-- Hibernate SessionFactory --><bean id="sessionFactory" class=""><!-- 引用前面定义的数据源 --><property name="dataSource" ref="dataSource"/><!-- 所有实体映射文件列表, 所有的文件 --><property name="mappingResources"><list><value>org/springframework/samples/jpetstore/domain/ 传统上的文件的参数放在这里 --><property name="hibernateProperties"><props><!-- 指定数据库方言 --><prop key="">${}</prop><!-- 是否在日志中输出所有Hibernate与数据库交互的SQL语句 --> <prop key="">true</prop><!-- 是否在日志中输出的SQL 语句格式化成易读形式 --><prop key="">true</prop><!-- 是否显示统计形式,一般在测试阶段使用 --><prop key="">true</prop><!-- 对于级联查询,一次性获取的级联深度, @todo 需进一步研究 --> <prop key="">2</prop><!--Fetch Size 是设定JDBC的Statement读取数据的时候每次从数据库中取出的记录条数,一般设置为30、50、100。

相关主题