1、加入DataSourceTransactionManager的命名空间
修改applicationContext.xml文件,增加如下内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <? xml version = "1.0" encoding = "UTF-8" ?> xsi:schemaLocation="http://www.springframework.org/schema/beans |
2、初始化HibernateTransactionManager
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | <? xml version = "1.0" encoding = "UTF-8" ?> xsi:schemaLocation="http://www.springframework.org/schema/beans < context:annotation-config /> < context:component-scan base-package = "com.fz.annotation" /> < bean class = "org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" > < property name = "locations" value = "classpath:jdbc.properties" /> </ bean > < bean id = "dataSource" destroy-method = "close" class = "org.apache.commons.dbcp.BasicDataSource" > < property name = "driverClassName" value = "${jdbc.driverClassName}" /> < property name = "url" value = "${jdbc.url}" /> < property name = "username" value = "${jdbc.username}" /> < property name = "password" value = "${jdbc.password}" /> </ bean > <!-- annotation方式管理hibernate的sessionFactory --> < bean id = "sessionFactory" class = "org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" > < property name = "dataSource" ref = "dataSource" /> < property name = "packagesToScan" > < list > < value >com.fz.annotation.model</ value > </ list > </ property > < property name = "hibernateProperties" > < props > < prop key = "hibernate.dialect" >org.hibernate.dialect.MySQLDialect</ prop > < prop key = "hibernate.show_sql" >true</ prop > < prop key = "hibernate.format_sql" >true</ prop > </ props > </ property > </ bean > < tx:annotation-driven transaction-manager = "myTxManager" /> < bean id = "myTxManager" class = "org.springframework.orm.hibernate3.HibernateTransactionManager" > < property name = "sessionFactory" ref = "sessionFactory" /> </ bean > </ beans > |
这里需要配置一个HibernateTransactionManager的bean和<
tx:annotation-driven
transaction-manager
=
"myTxManager"
/>
3、在Service层使用事务管理
userServiceImpl.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | package com.fz.annotation.service.impl; import javax.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.fz.annotation.dao.UserDao; import com.fz.annotation.model.User; import com.fz.annotation.service.UserService; @Service ( "userService" ) public class UserServiceImpl implements UserService{ private UserDao userDao; @Transactional public void userAdd(User user) { userDao.userAdd(user); } public UserDao getUserDao() { return userDao; } @Resource (name= "userDao" ) public void setUserDao(UserDao userDao) { this .userDao = userDao; } } |
注意:这里使用@Transactional注解来注明该方法需要使用到事务
userDaoImpl.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | package com.fz.annotation.dao.impl; import javax.annotation.Resource; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.springframework.stereotype.Repository; import com.fz.annotation.dao.UserDao; import com.fz.annotation.model.User; @Repository ( "userDao" ) public class UserDaoImpl implements UserDao{ private SessionFactory sessionFactory; public void userAdd(User user) { Session session = sessionFactory.getCurrentSession(); session.save(user); } public SessionFactory getSessionFactory() { return sessionFactory; } @Resource public void setSessionFactory(SessionFactory sessionFactory) { this .sessionFactory = sessionFactory; } } |
4、测试
测试正常情况,结果一切正常。数据库也插入了数据
1 2 3 4 5 6 7 8 9 | @Test public void getProperties(){ ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext( "applicationContext_aop.xml" ); UserService userService = (UserService) ctx.getBean( "userService" ); User user = new User(); user.setId( 4 ); user.setUsername( "test1" ); userService.userAdd(user); } |
修改userDaoImpl.java,抛出一个异常。看看是否能回滚
在userDaoImpl.java的userAdd方法中抛出一个异常
1 2 3 4 5 | public void userAdd(User user) { Session session = sessionFactory.getCurrentSession(); session.save(user); throw new RuntimeException( "aa" ); } |
然后再次测试的时候,发现数据库中没有插入该条数据。依然是上一次的数据
5、事务的传播特性Propagation
所谓传播特性:也就是Transaction的产生过程,以及事务来了后怎么管理这个事务。
@Transactional注解有个属性:Propagation,Propagation是一个枚举类型,默认是REQUIRED,枚举的值如下:
REQUIRED(默认,最常用,重要)
Support a current transaction, create a new one if none exists.