我们平时使用ssh开发项目的时候,在业务曾总是要添加各种事务以保证 数据的一致性,那么现在我们就看一下spring整合hibernate是如何实现事务管理的;
实现spring整合hibernate是声明式事务管理有两种方式:
1、annotation方式,主要是通过注解实现事务管理(方便,简单)
2、xml方式,主要是通过在spring.xml文件的事务管理配置 实现(易于修改)
一、annotation方式的声明式事务管理
-----------------------------1、首先配置spring.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/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"> <context:annotation-config></context:annotation-config> <context:component-scan base-package="com.phome"></context:component-scan> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> <!-- 加载数据源c3p0的配置文件 --> <context:property-placeholder location="jdbc.properties"/> <!-- 数据源c3p0的配置 --> <bean id="myDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="${jdbc.driverClassName}"/> <property name="jdbcUrl" value="${jdbc.url}"/> <property name="user" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean> <!-- 配置sessionFactory --> <bean id="mySessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="dataSource" ref="myDataSource"/> <!--<property name="annotatedClasses"> <list> <value>com.phome.modal.Student</value> </list> </property> --> <!-- 这个配置可以自动检索素要scan的实体类 --> <property name="packagesToScan"> <list> <value>com.phome.modal</value> </list> </property> <property name="hibernateProperties"> <value> <!-- SQL dialect --> hibernate.dialect=org.hibernate.dialect.MySQLDialect <!-- Enable Hibernate's automatic session context management --> hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext <!-- Echo all executed SQL to stdout --> hibernate.show_sql=true <!-- sql语句格式化 --> hibernate.format_sql=true <!-- Drop and re-create the database schema on startup --> hibernate.hbm2ddl.auto=update </value> </property> </bean> <!-- 配置事务管理器 --> <bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="mySessionFactory"></property> </bean> <!-- annotation声明式事务管理 --> <!-- 添加这个配置,spring就会自动扫描,开始有@Transaction 注解的方法,并在方法执行前后插入事务管理 --> <tx:annotation-driven transaction-manager="txManager" /> </beans>
---------------------------------------------2、在要添加事务的业务层 方法前 添加注解-------------------------------------------------------------
有了以上配置,只需要在需要添加事务的方法前 加入 注解 @Transaction 就好了
package com.phome.service; import javax.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.phome.dao.IDao; import com.phome.modal.Student; @Service("studentService") public class StudentService { private IDao studentDao; public IDao getStudentDao() { return studentDao; } @Resource(name="studentDao") public void setStudentDao(IDao studentDao) { this.studentDao = studentDao; } @Transactional public void save (Student s) { System.out.println("service_save() start..."); studentDao.save(s); System.out.println("service_save() end..."); } //添加事务注解 @Transactional public void delete (Student s) { System.out.println("service_delete() start..."); studentDao.delete(s); System.out.println("servicedelete() end..."); } }
二、xml方式的声明式事务管理
1、业务层的代码不需要在做任何修改,必要在添加任何代码,只需要配置xml就好(这样即使在没有源码的情况下,我们也可以对事务进行控制)
package com.phome.service; import javax.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.phome.dao.IDao; import com.phome.modal.Student; @Service("studentService") public class StudentService { private IDao studentDao; public IDao getStudentDao() { return studentDao; } @Resource(name="studentDao") public void setStudentDao(IDao studentDao) { this.studentDao = studentDao; } public void save (Student s) { System.out.println("service_save() start..."); studentDao.save(s); System.out.println("service_save() end..."); } public void delete (Student s) { System.out.println("service_delete() start..."); studentDao.delete(s); System.out.println("servicedelete() end..."); } }
2、配置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/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"> <context:annotation-config></context:annotation-config> <context:component-scan base-package="com.phome"></context:component-scan> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> <!-- 加载数据源c3p0的配置文件 --> <context:property-placeholder location="jdbc.properties"/> <!-- 数据源c3p0的配置 --> <bean id="myDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="${jdbc.driverClassName}"/> <property name="jdbcUrl" value="${jdbc.url}"/> <property name="user" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean> <bean id="mySessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="dataSource" ref="myDataSource"/> <!--<property name="annotatedClasses"> <list> <value>com.phome.modal.Student</value> </list> </property> --> <!-- 这个配置可以自动检索素要scan的实体类 --> <property name="packagesToScan"> <list> <value>com.phome.modal</value> </list> </property> <property name="hibernateProperties"> <value> <!-- SQL dialect --> hibernate.dialect=org.hibernate.dialect.MySQLDialect <!-- Enable Hibernate's automatic session context management --> hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext <!-- Echo all executed SQL to stdout --> hibernate.show_sql=true <!-- sql语句格式化 --> hibernate.format_sql=true <!-- Drop and re-create the database schema on startup --> hibernate.hbm2ddl.auto=update </value> </property> </bean> <!-- 配置事务管理器 --> <bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="mySessionFactory"></property> </bean> <!-- xml声明式事务管理(主要是通过spring的AOP配置实现的) --> <!-- 1、配置一个切面 --> <aop:config> <!-- 配置切入点,用切入点表达式告诉spring在哪里添加切面,把事务逻辑织入进去。(在com.phome.service包下的所有方法全部添加事务) --> <aop:pointcut expression="execution(public * com.phome.service..*.*(..))" id="transactionCutPoint"/> <aop:advisor advice-ref="transactionAdvise" pointcut-ref="transactionCutPoint"/> </aop:config> <!-- 配置一个advice,声明事务管理器 --> <tx:advice id="transactionAdvise" transaction-manager="txManager"> <!-- 配置事务管理器的一些属性 --> <tx:attributes> <!-- 这个表示在切入点表达式 说明的那些方法中,get*() 是只读的,这是事务的隔离性 --> <tx:method name="get*" read-only="true"/> <span style="white-space:pre"> </span><!-- 这个表示在切入点表达式 说明的那些方法中,save()要是本来就有事务,那就直接执行。要是没有事务,就创建事务执行。这是事务的传播特性 --> <tx:method name="save" propagation="REQUIRED"/> <tx:method name="delete" propagation="REQUIRED"/> </tx:attributes> </tx:advice> </beans>
这就是声明式事务管理配置,希望对大家能有所帮助。。。
谢谢