我们平时使用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>
这就是声明式事务管理配置,希望对大家能有所帮助。。。
谢谢