本文介绍Spring 的声明式事务配置,使用HibernateTransaction
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: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/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">
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocations">
<value>classpath:hibernate.cfg.xml</value>
</property>
</bean>
<bean id="userDao" class="com.dao.impl.UserDaoImpl">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<bean id="logDao" class="com.dao.impl.LogDaoImpl">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<bean id="userService" class="com.service.UserService">
<property name="userDao" ref="userDao"></property>
<property name="logDao" ref="logDao"></property>
</bean>
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<aop:config>
<!-- global pointcut -->
<aop:pointcut expression="execution(* com.service.*.save(..))"
id="service" />
<aop:advisor pointcut-ref="service"
advice-ref="txAdvice" />
</aop:config>
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<!-- service层里面的方法,不是dao层里面的方法 -->
<tx:method name="save*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
</beans>
hibernate.cfg.xml配置文件
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/spring</property>
<property name="connection.username">root</property>
<property name="connection.password">zizhu</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">10</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<!-- 此处千万不能打开,否则会报错,第一次就卡在这个地方,这个地方可以直接让spring自己默认配置 -->
<!-- <property name="current_session_context_class">thread</property>-->
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<!-- <property name="show_sql">true</property>-->
<property name="format_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">update</property>
<!-- <mapping resource="com/model/User.hbm.xml"/>-->
<mapping class="com.model.User"/>
<mapping class="com.model.Log"/>
</session-factory>
</hibernate-configuration>
service层的核心类:
package com.service;
import com.dao.LogDao;
import com.dao.UserDao;
import com.model.Log;
import com.model.User;
public class UserService {
private UserDao userDao=null;
private LogDao logDao=null;
public LogDao getLogDao() {
return logDao;
}
public void setLogDao(LogDao logDao) {
this.logDao = logDao;
}
/**
* 事务的边界只能在service层,当在保存用户或者日志时,任何一个地方出错,
* 这个事务都将回滚,这就是为什么事务的边界需要配置在service层的原因
* @param user
*/
public void save(User user){
userDao.save(user);
Log log = new Log();
log.setContent("a user saved");
logDao.save(log);
}
public UserDao getUserDao() {
return userDao;
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}
在UserDao的具体实现类中不需要session.beginTransaction(),也不需要session.getTransaction().commit();因为由spring管理事务了
package com.dao.impl;
import org.hibernate.SessionFactory;
import org.hibernate.classic.Session;
import com.dao.UserDao;
import com.model.User;
public class UserDaoImpl implements UserDao{
private SessionFactory sessionFactory = null;
public SessionFactory getSessionFactory() {
return sessionFactory;
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public void save(User user) {
Session session = sessionFactory.getCurrentSession();
/**
* 此处直接保存,不需要beginTransaction()
*/
session.save(user);
/**
* 最后也不需要commit()
* 由spring管理事务
*/
System.out.println("Save user:"+user.getUsername());
}
}
Spring 声明式Transaction,在项目中用的相当多,因此留个备份,方便以后copy改……