0 0

Spring整合Hibernate后调用session.save方法报错但事务不回滚0

在DAO的saveRecord方法中执行session.save后,手动让程序throw了一个Exception,然而事务没有回滚,而让这条记录增到了数据库中,这是什么原因?

我使用的Spring声明式事务管理,事务管理器是"..orm.hibernate4.HibernateTransactionManager",具体见配置文件,Spring版本4.0.2,Hibernate版本4.3.5,使用的数据库是MySQL,是不是Spring事务管理器没有对这个方法起作用,恰好Hibernate或者MySQL是自动提交的?
package com.sample.dao.impl;

import java.io.Serializable;
import java.util.List;

import javax.annotation.Resource;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.stereotype.Repository;

import com.sample.dao.BaseDAO;
import com.sample.po.Employee;

@Repository("empDAOHiber")
public class EmpDAOHibernate extends BaseDAO<Employee> {
	
	private SessionFactory sessionFactory;
	
	@Resource
	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

	private Session getCurSession(){
		return sessionFactory.getCurrentSession();
	}

	@Override
	public Serializable saveRecord(Employee obj) throws Exception{
		Serializable s1 = this.getCurSession().save(obj);
		if(1 == 1){
			throw new Exception("xxxxxxxxxxxxx!!!!");
		}
		return s1;
	}
	
}


下面是配置文件:看不清的请下附件
<?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.xsd
           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
    <!-- 开启切面 -->
	<aop:aspectj-autoproxy />
	<!-- 打开注解 -->
	<context:annotation-config />
	<!-- 打开自动扫描 -->
	<context:component-scan base-package="com.sample.dao.impl" />
    <!-- 加载properties文件 -->
	<context:property-placeholder location="classpath:jdbc-datasource.properties" />
	<!-- 定义DataSource -->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName" value="${driverClassName}" />
		<property name="url" value="${url}" />
		<property name="username" value="${username}" />
		<property name="password" value="${password}" />
		<!-- 连接池启动时的初始值 -->
		<property name="initialSize" value="${initialSize}" />
		<!-- 连接池的最大值 -->
		<property name="maxActive" value="${maxActive}" />
		<!-- 最大空闲值.当经过一个高峰时间后,连接池可以慢慢将已经用不到的连接慢慢释放一部分,一直减少到maxIdle为止 -->
		<property name="maxIdle" value="${maxIdle}" />
		<!--  最小空闲值.当空闲的连接数少于阀值时,连接池就会预申请去一些连接,以免洪峰来时来不及申请 -->
		<property name="minIdle" value="${minIdle}" />
	</bean>
	
	<!-- Hibernate Session 工厂 -->  
    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">  
        <property name="dataSource">  
            <ref local="dataSource" />
        </property>
        <property name="configLocation" value="classpath:hibernate.cfg.xml"/>  
        <!-- 自动扫描注解方式配置的hibernate类文件 -->  
        <property name="packagesToScan">  
            <list>  
                <value>com.sample.po</value>
            </list>  
        </property>  
    </bean>  
  
    <!-- 配置事务管理器 -->  
    <bean id="txManager"  
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">  
        <property name="sessionFactory">
        	<ref local="sessionFactory" />
        </property>  
    </bean>  
	
	<!-- 声明式事务(配置方式) -->
	<tx:advice id="txAdvice" transaction-manager="txManager">
		<tx:attributes>
			<tx:method name="save*" propagation="REQUIRED" />
			<tx:method name="update*" propagation="REQUIRED" />
			<tx:method name="delete*" propagation="REQUIRED" />
			<tx:method name="save*" propagation="REQUIRED" />
			<tx:method name="execute*" propagation="REQUIRED" />
			
			<tx:method name="get*" propagation="REQUIRED" read-only="true" />
			<tx:method name="find*" propagation="REQUIRED" read-only="true" />
			<tx:method name="*" propagation="REQUIRED" read-only="true" />
		</tx:attributes>
	</tx:advice>
	
	<aop:config>
		<aop:pointcut id="transactionPointcut"
			expression="execution(* com.sample..dao.impl.*.*(..))" />
		<aop:advisor advice-ref="txAdvice" pointcut-ref="transactionPointcut" />
	</aop:config>
</beans>

2014年5月25日 20:29

5个答案 按时间排序 按投票排序

0 0

怀疑是你的
<aop:config> 
        <aop:pointcut id="transactionPointcut" 
            expression="execution(* com.sample..dao.impl.*.*(..))" /> 
        <aop:advisor advice-ref="txAdvice" pointcut-ref="transactionPointcut" /> 
    </aop:config> 

这个配置的有问题,一般的aop:pointcut  里面的包的路径应该是service这一层,你配置到dao这层去了,你换个试试!

2014年5月30日 16:44
0 0

还有,一般基于注解都是这么写的:

	@Resource
	public SessionFactory sessionFactory;
	
	public Session getSession(){
		return sessionFactory.getCurrentSession();
	}
	
	@Resource
	public JdbcTemplate jdbcTemplate;

	<!-- 事务管理 -->
	<bean id="transactionManager"
			class="org.springframework.orm.hibernate3.HibernateTransactionManager">
			<property name="sessionFactory" ref="sessionFactory" />
	</bean>
	
	<!-- 基于注解方式的事物管理 -->
	<tx:annotation-driven transaction-manager="transactionManager"/>
	
    <!-- jdbcTemplate -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

2014年5月26日 19:11
0 0

有可能是 MySQL 引擎的问题。查看一下 MySQL 表的引擎是什么,如果是 MyISAM,那就是不支持事务的。

2014年5月26日 13:54
0 0

如果采用三层架构:controller->service->dao,那么既然你在dao抛出异常,应该要在service捕获,如果service不捕获,就必须在controller捕获
service可写为:

@Service("trainService")
@Transactional
public class TrainServiceImpl implements TrainService{
     public JSONArray a(){
         try{
             //TODO
         }catch(Exception e){
             e.printstacttrace();
         }
     }
}

或者controller
@Controller
@RequestMapping("/train.do")
public class TrainController {
@RequestMapping(params = "method=addClass")
	@Transactional(rollbackFor = Exception.class)
	public void addClass(HttpServletRequest request, HttpServletResponse response) {
		try{
                //TODO
}catch(e){

}

}

}

2014年5月26日 12:15
0 0

aop:config
expression=com.sample.dao.impl.*

2014年5月25日 20:36

相关推荐

    spring与hibernate的整合

    这样,Spring 会在调用 `addDepartment()` 方法时自动开启、提交或回滚事务,无需在业务代码中手动管理。 总结来说,Spring 与 Hibernate 的整合主要涉及 SessionFactory 的配置、DAO 类的实现以及事务管理。通过 ...

    spring+hibernate整合实现简单数据库添加记录

    Spring的事务管理会确保在成功保存后提交事务,如果出现异常则回滚。 8. **测试**:最后,编写单元测试或集成测试来验证添加记录的功能是否正常工作。可以使用Spring的TestContext框架和JUnit进行测试。 总之,...

    Spring和Hibernate的整合操作示例

    整合Spring和Hibernate的主要目的是利用Spring的管理能力来控制Hibernate的SessionFactory和Session,以及事务管理。下面我们将详细探讨整合的步骤和方法。 1. **配置环境**: - 首先,确保你的项目中包含了Spring...

    spring和hibernate集成Demo

    5. **Service层**: 定义业务逻辑,调用DAO层方法,Spring会自动处理事务的开始、提交或回滚。 **示例代码片段** 在Spring 2.5和Hibernate 3.3的集成Demo中,可能包含以下关键部分: ```xml &lt;!-- Spring配置文件中...

    spring3、 hibernate4 配置声明式事务管理(annotation方式)

    `HibernateTransactionManager`是Spring提供的专门用于管理Hibernate事务的类,它会自动处理Hibernate Session和JDBC Connection的开启、提交、回滚。 三、配置Spring事务管理 在Spring的配置文件中,我们需要添加...

    用Hibernate和Spring开发事务持久层.rar_spring

    Spring通过AOP代理在合适的时候调用Hibernate的Session方法,控制事务的开启、提交、回滚等行为。以下是一段示例代码,展示了如何在Spring中配置Hibernate事务管理: ```xml &lt;bean id="sessionFactory" class="org....

    Hibernate事务(源码)

    在Hibernate中,事务的开始通常通过`Session.beginTransaction()`方法启动,而结束则分为提交和回滚两种情况。如果事务执行成功,调用`Transaction.commit()`方法提交事务;如果发生异常,调用`Transaction.rollback...

    spring hibernate 整合例子

    使用SessionFactory的openSession()方法获取Session,然后调用Session的save()或saveOrUpdate()方法保存对象到数据库。 6. **测试**:创建测试类,使用JUnit或其他测试框架,调用Service类的insert方法,检查数据...

    Spring控制Hibernate中的事务传播特性与隔离级别操作.docx

    在Spring中,事务的传播特性(Transaction Propagation)决定了在一个事务方法被调用时,另一个事务方法应该如何运行。例如,PROPAGATION_REQUIRED表示如果当前存在事务,则加入到当前事务,如果当前没有事务,则...

    Struts2整合Spring Hibernate的CRUD实例

    - **删除(Delete)**:删除数据时,找到要删除的对象,调用Session的delete()方法,然后提交事务。 5. **事务管理**:Spring提供了强大的事务管理功能。在Service层的方法上添加@Transactional注解,可以声明式地...

    收集的struts+spring+hibernate面试题.doc

    ### Struts + Spring + Hibernate 面试题解析 #### 1. AOP 和 IOC 的概念以及在 Spring 中的应用 **AOP(Aspect Oriented Programming,面向切面编程)**: 是一种编程思想,它允许程序员定义“切面”来封装那些...

    spring3+hibernate4声明式事务配置(xml方式)

    6. **在服务层使用@Transactional**:现在,你可以在服务层方法上添加@Transactional注解,Spring会在调用这些方法时自动开启和提交/回滚事务。 ```java @Service public class UserService { @Autowired private...

    Spring MVC+Spring+Hibernate实现简单的增删查改

    接下来,定义Spring MVC的Controller,这里可以创建四个方法:`save()`, `delete()`, `update()`, `list()`,分别对应增、删、改、查操作。Controller将接收到的请求转发给相应的Service层,Service层调用DAO层执行...

    hibernate最简单源代码

    - 更新:修改对象状态后,调用`Session.update()`或`Session.merge()`方法更新数据库记录。 - 删除:调用`Session.delete()`方法删除数据库中的记录。 - 查询:通过`Session.get()`获取单个对象,`Session.load()...

    hibernate与struts增删改查整合实例源代码

    对于"增"操作,开发者通常会在Action中创建新对象,设置属性,然后调用`Session.save()`或`Session.persist()`方法。"删"操作对应`Session.delete()`,"改"是找到要修改的对象,更新其属性,最后`Session.update()`...

    struts2+spring+hibernate分页,事务,自定义切面

    Hibernate Session与数据库的交互是在事务内部进行的,因此,我们需要在Spring的事务边界内调用Hibernate的相关操作,如save()、update()、delete()和query()。 至于自定义切面,这是Spring AOP(面向切面编程)的...

    Hibernate+Spring增删改查小例子

    7. **事务管理**:在Spring中,可以使用声明式事务管理,通过在Service方法上添加`@Transactional`注解,让Spring自动处理事务的开始、提交或回滚。 8. **HQL(Hibernate查询语言)**:Hibernate提供了一种面向对象...

    spring_hibernate_annotation的三种实现

    - 在实现类中,使用`SessionFactory`的`openSession()`方法获取`Session`,然后调用`Session`的方法执行CRUD操作,如`save()`, `get()`, `update()`, `delete()`等。 6. 示例代码: ```java @Repository public...

    struts2整合hibernate

    7. **事务管理**:整合Struts2和Hibernate时,需要考虑事务边界,通常在业务逻辑的开始开启事务,在结束时提交或回滚。可以使用Spring的AOP来管理事务,或者在Action中手动控制。 8. **Action与DAO交互**:在Action...

    hibernate封装.pdf

    同样,它在事务中进行操作,先开始事务,然后调用`session.delete(object)`来删除对象,最后处理事务的提交或回滚。 5. **异常处理**:在所有涉及数据库操作的方法中,都使用了异常处理机制,捕获`...

Global site tag (gtag.js) - Google Analytics