问题描述
我的applicationContext.xml配置如下:<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-3.0.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-3.0.xsd"><bean name="S3Impl" class="cn.xiaoxing.s3.dao.impl.S3Impl"><property name="sessionFactory" ref="dbConfig"></property></bean><bean name="dataSource" class="org.apache.commons.dbcp.BasicDataSource"><property name="driverClassName"><value>com.mysql.jdbc.Driver</value></property><property name="url"><value>jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8</value></property><property name="username" value="root"></property><property name="password" value="123456"></property></bean><bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <tx:advice id="txAdvice" transaction-manager="txManager"><tx:attributes><tx:method name="get*" read-only="true" /><tx:method name="*" /></tx:attributes></tx:advice><aop:config><aop:pointcut id="myPointCut" expression="execution(* cn.xiaoxing.s3.dao.impl.*.*(..))"/><aop:advisor advice-ref="txAdvice" pointcut-ref="myPointCut"/></aop:config><!-- 在Spring的application context中创建 SessionFactory --><bean id="dbConfig" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"><property name="dataSource" ref="dataSource"></property><!-- 资源注册 --><property name="mappingResources"><list><value>cn/xiaoxing/s3/vo/UserModel.hbm.xml</value></list></property><!-- 可选配置 --><property name="hibernateProperties"><props><prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop><prop key="hibernate.show_sql">true</prop><prop key="hibernate.format_sql">true</prop><prop key="hibernate.current_session_context_class">thread</prop></props></property></bean></beans> DAO实现部分代码如下:@Overridepublic boolean create(UserModel um) {Session session = sessionFactory.getCurrentSession();session.save(um);/*Transaction ts = session.beginTransaction();try{session.save(um);ts.commit();}catch(Exception err){ts.rollback();err.printStackTrace();return false;}*/return true;} 报错信息如下:Exception in thread "main" org.hibernate.HibernateException: save is not valid without active transactionat org.hibernate.context.internal.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:348)at $Proxy5.save(Unknown Source)at cn.xiaoxing.s3.dao.impl.S3Impl.create(S3Impl.java:22)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)at java.lang.reflect.Method.invoke(Unknown Source)at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:91)at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)at $Proxy4.create(Unknown Source)at cn.xiaoxing.s3.Client.main(Client.java:20) 我的问题是,如果按照上面代码执行的时候会报上面的错误,但如果我在DAO实现类中写hibernate事务后,就可以正常插入数据了,我想显然是因为配置的事务没有生效的缘故,自己折腾了半天也没有搞好,所以请各位帮忙指点。我用的版本:spring3.2.2 hibernate4
解决方案
DataSourceTransactionManager 缓存HibernateTransactionManager
解决方案二:
对单个数据源,使用HibernateTransactionManager正确,DataSourceTransactionManager错误;1.以上配置成功的应用了事务拦截器,当create被调用时成功的开启了事务2.激活事务方式:前者代理到org.hibernate.JDBCTransaction.begin方法,使用缓存标识事务是否激活;后者缓存标识到DataSourceTransactionManager中;3.getCurrentSession时,原生的org.hibernate.Session使用JDK动态代理,对session自身操作方法要求:在操作之前,是否激活事务,而这个判断的关键依赖于JDBCTransaction4.使用DataSourceTransactionManager的缓存标识此时用不到,而使用HibernateTransactionManager正好利用JDBCTransaction缓存标识
解决方案三:
<aop:config> <aop:pointcut id="myPointCut" expression="execution(* cn.xiaoxing.s3.dao.impl.*.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="myPointCut"/> </aop:config> 切面好像不对吧