当前位置: 代码迷 >> J2EE >> 【贴】spring和hibernate整合之后事务不能回滚
  详细解决方案

【贴】spring和hibernate整合之后事务不能回滚

热度:34   发布时间:2016-04-17 22:56:23.0
【求助贴】spring和hibernate整合之后事务不能回滚
小弟新手,学习spring没有多长时间,求大神帮忙~
spring整合了hibernate之后能正常插入数据,但是出现异常之后不能回滚。
首先,测试代码:
public void testOne(){
ApplicationContext context=new ClassPathXmlApplicationContext("com/kdyzm/spring/hibernate/xml/applicationContext.xml");
CourseService courseService=(CourseService) context.getBean("courseService");
Course course = new Course();
// course.setCid(11L);
course.setCname("赵日天");
courseService.addCourse(course);
course =new Course();
course.setCname("王大锤");
//通过/0的异常测试事务回滚!
int a=1/0;
courseService.addCourse(course);
}


运行结果:

com.kdyzm.spring.hibernate.xml.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-2.5.xsd
           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
           ">
    <!-- 将hibernate.cfg.xml配置文件导入进来 -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
     <property name="configLocation">
     <value>classpath:hibernate.cfg.xml</value>
     </property>
    </bean>
    
    <!-- 程序员做的事情 -->
    <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
     <property name="sessionFactory" ref="sessionFactory"></property>
    </bean>
    <bean id="courseDao" class="com.kdyzm.spring.hibernate.xml.CourseDaoImpl">
     <property name="hibernateTemplate">
     <ref bean="hibernateTemplate"/>
     </property>
    </bean>
    
    <bean id="courseService" class="com.kdyzm.spring.hibernate.xml.CourseServiceImpl">
     <property name="courseDao">
     <ref bean="courseDao"/>
     </property>
    </bean>
    
    <!-- Spring容器做的事情 -->
    <!-- 定义事务管理器 -->
    <bean id="hibernateTransactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
     <property name="sessionFactory" ref="sessionFactory"></property>
    </bean>
    <!-- 哪些通知需要开启事务模板 -->
    <tx:advice id="advice" transaction-manager="hibernateTransactionManager">
     <tx:attributes>
     <tx:method name="add*" isolation="DEFAULT" propagation="REQUIRED" read-only="false"/>
     </tx:attributes>
    </tx:advice>
    <!-- 配置切面表达式和通知 -->
    <aop:config>
     <aop:pointcut expression="execution(* com.kdyzm.spring.hibernate.xml.*ServiceImpl.*(..))" id="perform"/>
     <aop:advisor advice-ref="advice" pointcut-ref="perform"/>
    </aop:config>
</beans>

com.kdyzm.spring.hibernate.CourseDaoImpl.java
package com.kdyzm.spring.hibernate.xml;

import org.springframework.orm.hibernate3.HibernateTemplate;

public class CourseDaoImpl implements CourseDao{
//这里使用HibernateTemplate,而不是使用JdbcTemplate
private HibernateTemplate hibernateTemplate;
public HibernateTemplate getHibernateTemplate() {
return hibernateTemplate;
}

public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
this.hibernateTemplate = hibernateTemplate;
}

@Override
public Course getCourse(Long cid) {
return (Course) this.hibernateTemplate.get(Course.class, cid);
}

@Override
public Course updateCourse(Course course) {
this.hibernateTemplate.update(course);
return course;
}

@Override
public Course deleteCourse(Course course) {
this.hibernateTemplate.delete(course);
return course;
}

@Override
public Course addCourse(Course course) {
this.hibernateTemplate.saveOrUpdate(course);
return course;
}

}

hibernate.cfg.xml配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="connection.username">root</property>
<property name="connection.password">5a6f38</property>
<property name="connection.url">
jdbc:mysql://localhost:3306/test
</property>
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">update</property>
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="javax.persistence.validation.mode">none</property>
<mapping resource="com/kdyzm/spring/hibernate/xml/Course.hbm.xml" />
</session-factory>
</hibernate-configuration>

------解决思路----------------------
對的,你配置的事務是在Service層,因此你的業務層抛出異常并不影響事務的成功與否(當Service層方法返回之後,事務就已經完成),因此你的測試應該將抛異常移到Service層,或者將你的測試類的方法加入到事務中。
  相关解决方案