Spring融合Hibernate事务管理

来源:互联网 发布:无线扫描器 软件 编辑:程序博客网 时间:2024/06/10 14:58
Java代码 复制代码
  1. <!--第一部分 数据源-->   
  2.   
  3. <bean id="dataSource"  
  4.   class="org.apache.commons.dbcp.BasicDataSource">   
  5.   <property name="driverClassName">   
  6.    <value>com.mysql.jdbc.Driver</value>   
  7.   </property>   
  8.   <property name="url">   
  9.    <value>jdbc:mysql://localhost/test?useUnicode=true&characterEncoding=UTF-8</value>   
  10.   </property>   
  11.   <property name="username">   
  12.    <value>root</value>   
  13.   </property>   
  14.   <property name="password">   
  15.    <value>root</value>   
  16.   </property>   
  17.  </bean>   
  18.   
  19. <!--第二部分 hibernate的配置-->   
  20.   
  21.  <bean id="exampleHibernateProperties"    
  22. class="org.springframework.beans.factory.config.PropertiesFactoryBean">   
  23.   <property name="properties">   
  24.    <props>   
  25.     <prop key="hibernate.hbm2ddl.auto">update</prop>   
  26.     <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>   
  27.     <prop key="hibernate.query.substitutions">true '0'false '1'</prop>   
  28.     <prop key="hibernate.show_sql">true</prop>   
  29.     <prop key="hibernate.c3p0.minPoolSize">5</prop>   
  30.     <prop key="hibernate.c3p0.maxPoolSize">20</prop>   
  31.     <prop key="hibernate.c3p0.timeout">600</prop>   
  32.     <prop key="hibernate.c3p0.max_statement">50</prop>   
  33.     <prop key="hibernate.c3p0.testConnectionOnCheckout">false</prop>   
  34.    </props>   
  35.   </property>   
  36.  </bean>   
  37.   
  38. <!--第三部分 hibernate的sessionFactory 一个关联于特定数据库的全局工厂-->   
  39.   
  40.  <bean id="sessionFactory"  
  41.   class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">   
  42.   <property name="dataSource">   
  43.    <ref bean="dataSource" />//先前定义的数据源   
  44.   </property>   
  45.   <property name="mappingResources">   
  46.    <list>   
  47.           <value>Test.hbm.xml</value>//hibernate O/R map文件   
  48.       </list>   
  49.   </property>   
  50.   <property name="hibernateProperties">   
  51.    <ref bean="exampleHibernateProperties" />//先前定义的hibernate 配置   
  52.   </property>   
  53.  </bean>   
  54.   
  55. <!--第四部分 事务 transactionManager-->   
  56.   
  57. <bean id="transactionManager"  
  58.   class="org.springframework.orm.hibernate3.HibernateTransactionManager"  
  59.   abstract="false" singleton="true" lazy-init="default"  
  60.   autowire="default" dependency-check="default">   
  61.   <property name="sessionFactory">   
  62.    <ref bean="sessionFactory" />//先前定义的sessinFactory   
  63.   </property>   
  64.  </bean>   
  65.   
  66. <!--第五部分 Dao 抽象-->   
  67.   
  68. <bean id="baseDao" abstract="true" singleton="false">   
  69.   <property name="sessionFactory" ref="sessionFactory"/>   
  70.  </bean>   
  71. 定义baseDao的好处就是在以下的Dao中再不用每个bean 都要注入sessionFactory了   
  72.   
  73. <!--第六部分 Dao-->   
  74.   
  75. <bean id="testDao" parent="baseDao"  //继承于先前定义的Dao 抽象   
  76.     class="ssh.naxj.dao.TestDao" singleton="true"/>   
  77.   
  78. <!--第七部分 定义 Target(BO)-->   
  79.   
  80.  <bean id="testBoTarget" class="ssh.naxj.bo.TestBo" singleton="true">   
  81.   <property name="testDao" ref="testDao"/>//IOC 注入testDao   
  82.  </bean>   
  83.   
  84. <!--第八部分 使用事务的BO-->   
  85.   
  86. <bean id="testBo"     
  87. class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">   
  88.   <property name="transactionManager">   
  89. <ref local="transactionManager"/>//transactionManager   
  90. </property>   
  91.   <property name="target"><ref local="testBoTarget"/></property>//Target   
  92.   <property name="transactionAttributes">   
  93.    <props>   
  94.     <prop key="*">PROPAGATION_REQUIRED</prop>//“*”为所有的方法使用事务   
  95.    </props>   
  96.   </property>   
  97.  </bean>  


OK,大功告成...

======================================================================

Spring配置事务在DAO层和业务逻辑层

Spring通过AOP实现声明式事务管理。通常通过TransactionProxyFactoryBean设置Spring事务代理。我们需要一个目标对象包装在事务代理中。这个目标对象一般是一个普通Java对象的bean。当我们定义TransactionProxyFactoryBean时,必须提供一个相关的 PlatformTransactionManager的引用和事务属性。事务属性含有上面描述的事务定义。

HibernateTransactionManager需要一个SessionFactory的引用

一.把事务放置在了DAO层:

Java代码 复制代码
  1. <!—hibernateTransactionManager-->   
  2.   
  3. <bean id="transactionManager"  
  4.   
  5.        class="org.springframework.orm.hibernate3.HibernateTransactionManager">   
  6.   
  7.        <property name="sessionFactory">   
  8.   
  9.               <ref local="sessionFactory" />   
  10.   
  11.        </property>   
  12.   
  13. </bean>   
  14.   
  15. <!—DAO层接口实现-->   
  16.   
  17. <bean id="companyDAOTarget"  
  18.   
  19.        class="com.vstsoft.querycompany.dao.impl.CompanyDAOImpl">   
  20.   
  21.        <property name="sessionFactory">   
  22.   
  23.               <ref local="sessionFactory" />   
  24.   
  25.        </property>   
  26.   
  27. </bean>   
  28.   
  29. <!—spring对DAO层的事务代理-->   
  30.   
  31. <bean id="companyDAOProxy"  
  32.   
  33.        class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">   
  34.   
  35.        <property name="transactionManager">   
  36.   
  37.               <ref bean="transactionManager" />   
  38.   
  39.        </property>   
  40.   
  41.        <property name="target">   
  42.   
  43.               <ref local="companyDAOTarget" />   
  44.   
  45.        </property>   
  46.   
  47.        <property name="transactionAttributes">   
  48.   
  49.               <props>   
  50.   
  51.               <prop key="insert*">PROPAGATION_REQUIRED</prop>   
  52.   
  53.               <prop key="delete*">PROPAGATION_REQUIRED</prop>   
  54.   
  55.               <prop key="find*">   
  56.   
  57.               PROPAGATION_REQUIRED,readOnly   
  58.   
  59.               </prop>   
  60.   
  61.               </props>   
  62.   
  63.        </property>   
  64.   
  65. </bean>   
  66.   
  67. <!—业务层接口实现,把DAO注入到Service里面-->   
  68.   
  69. <bean name="companyManageTarget"  
  70.   
  71.        class="com.vstsoft.querycompany.service.impl.CompanyManageTarget">   
  72.   
  73.        <property name="companyDAO">   
  74.   
  75.               <ref bean="companyDAOProxy" />   
  76.   
  77.        </property>   
  78.   
  79. </bean>   
  80.   
  81. <!—spring对Service层的代理-->   
  82.   
  83. <bean id="companyManageProxy"  
  84.   
  85.        class="org.springframework.aop.framework.ProxyFactoryBean">   
  86.   
  87.        <property name="proxyInterfaces">   
  88.   
  89.               <value>com.vstsoft.querycompany.service.CompanyManage</value>   
  90.   
  91.        </property>   
  92.   
  93.        <property name="target">   
  94.   
  95.               <ref bean="companyManageTarget" />   
  96.   
  97.        </property>   
  98.   
  99. </bean>   
  100.   
  101. <!—配置struts访问,把service层注入到action里面-->   
  102.   
  103. <bean name="/company"  
  104.   
  105.        class="com.vstsoft.querycompany.web.action.CompanyAction" singleton="false">   
  106.   
  107.        <property name="companyManage">   
  108.   
  109.               <ref local="companyManageProxy" />   
  110.   
  111.        </property>   
  112.   
  113. </bean>  


二.把事务放置在了Service层:

Java代码 复制代码
  1. <!—jtaTransactionManager-->   
  2.   
  3. <bean id="jtaTransactionManager"  
  4.   
  5.        class="org.springframework.transaction.jta.JtaTransactionManager" />   
  6.   
  7. <!—DAO层接口实现-->   
  8.   
  9. <bean id="companyDAOTarget"  
  10.   
  11.        class="com.vstsoft.querycompany.dao.impl.CompanyDAOImpl">   
  12.   
  13.        <property name="sessionFactory">   
  14.   
  15.               <ref local="sessionFactory" />   
  16.   
  17.        </property>   
  18.   
  19. </bean>   
  20.   
  21. <!—spring对DAO层的代理-->   
  22.   
  23. <bean id="companyDAOProxy"  
  24.   
  25.        class="org.springframework.aop.framework.ProxyFactoryBean">   
  26.   
  27.        <property name="proxyInterfaces">   
  28.   
  29.               <value>com.vstsoft.querycompany.dao.CompanyDAO</value>   
  30.   
  31.        </property>   
  32.   
  33.        <property name="target">   
  34.   
  35.               <ref bean="companyDAOTarget" />   
  36.   
  37.        </property>   
  38.   
  39. </bean>   
  40.   
  41. <!—业务层接口实现,把DAO注入到Service里面-->   
  42.   
  43. <bean name="companyManageTarget"  
  44.   
  45.        class="com.vstsoft.querycompany.service.impl.CompanyManageTarget">   
  46.   
  47.        <property name="companyDAO">   
  48.   
  49.               <ref bean="companyDAOProxy" />   
  50.   
  51.        </property>   
  52.   
  53. </bean>   
  54.   
  55. <!—spring代理业务层的事务管理-->   
  56.   
  57. <bean id="companyManageProxy"  
  58.   
  59.        class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">   
  60.   
  61.        <property name="transactionManager">   
  62.   
  63.               <ref local="jtaTransactionManager" />   
  64.   
  65.        </property>   
  66.   
  67.        <property name="transactionAttributes">   
  68.   
  69.               <props>   
  70.   
  71.                      <prop key="set*">PROPAGATION_REQUIRED</prop>   
  72.   
  73.                      <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>   
  74.   
  75.               </props>   
  76.   
  77.        </property>   
  78.   
  79.        <property name="target">   
  80.   
  81.               <ref bean="companyManageTarget" />   
  82.   
  83.        </property>   
  84.   
  85. </bean>   
  86.   
  87. <!—配置struts访问,把service层注入到action里面-->   
  88.   
  89. <bean name="/company"  
  90.   
  91.        class="com.vstsoft.querycompany.web.action.CompanyAction" singleton="false">   
  92.   
  93.        <property name="companyManage">   
  94.   
  95.               <ref local="companyManageProxy" />   
  96.   
  97.        </property>   
  98.   
  99. </bean>  


在service层的接口实现CompanyManageImpl里面有个setData方法:按顺序执行数据查询,数据删除,数据插入数据库行为,如果哪一步出异常(运行时异常),事务回滚,只有所有行为都没成功,事务提交。

===========================================================================

简单来说,就是因为lazy的问题,采用了org.springframework.orm.hibernate3.support.OpenSessionInViewFilter,
但是这东东不太友好哦!

目前我的解决办法如下:
spring原码不用改,
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter只管在web.xml文件里加载,不用带任何参数,
在业务层继承一个父类来管理事务:
Java代码 复制代码
  1. <?xml version="1.0" encoding="UTF-8"?>   
  2. <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"    
  3. "http://www.springframework.org/dtd/spring-beans.dtd">   
  4. <beans>   
  5.     <!--Base TransactionProxyed Service Bean-->   
  6.     <bean id="baseTxService"    
  7. class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"  
  8.           abstract="true">   
  9.         <property name="transactionManager" ref="transactionManager"/>   
  10.         <property name="proxyTargetClass" value="true"/>   
  11.   
  12.         <property name="transactionAttributes">   
  13.             <props>   
  14.                 <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>   
  15.                 <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>   
  16.                 <prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>   
  17.                 <prop key="save*">PROPAGATION_REQUIRED</prop>   
  18.                 <prop key="update*">PROPAGATION_REQUIRED</prop>   
  19.                 <prop key="remove*">PROPAGATION_REQUIRED</prop>   
  20.                 <prop key="set*">PROPAGATION_REQUIRED</prop>   
  21.                 <prop key="change*">PROPAGATION_REQUIRED</prop>   
  22.                 <prop key="delete*">PROPAGATION_REQUIRED</prop>   
  23.             </props>   
  24.         </property>   
  25.         <property name="preInterceptors">   
  26.             <list>   
  27.                 <ref bean="methodSecurityInterceptor"/>   
  28.             </list>   
  29.         </property>   
  30.     </bean>   
  31. </beans>   
  32. //-----------------------------------------------------------------   
  33.     <bean id="infopathManager" parent="baseTxService" autowire="byName">   
  34.         <property name="target">   
  35.             <bean class="com.gdlinkway.ebop.infopath.manager.InfopathManager"/>   
  36.         </property>   
  37.     </bean>   
原创粉丝点击