本文介绍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改……