Spring学习笔记-事务
回顾事务
- 把一组业务当成一个业务来做:要么都成功,要么都失败
- 事务在项目的开发中十分重要,涉及到数据的一致性问题
- 确保完整性和一致性
事务的ACID原则:
- 原子性:指一个事务是不可再分的工作单位,一个事务内的操作要么都执行,要么都不执行
- 一致性:指事务发生前后的逻辑保持一致性,事务的完整性约束没有被破坏
- 隔离性:多个事务间互相隔离,不会互相影响,防止数据破坏
- 持久性:事务一旦提交,就会被持久化至存储器中
Spring中的事务管理
-
编程式事务:需要在代码中进行事务的管理
-
声明式事务:AOP
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.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.xsd"> <!--配置数据源--> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="username" value="root"/> <property name="password" value="111111"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8"/> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> </bean> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="configLocation" value="classpath:mybatis-config.xml"/> <property name="mapperLocations" value="classpath:com/alb/mapper/*.xml"/> </bean> <bean id="userMapper" class="com.alb.mapper.UserMapperImpl"> <property name="sqlSessionFactory" ref="sqlSessionFactory"/> </bean> <!--配置声明式事务--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <constructor-arg ref="dataSource"/> </bean> <!--结合AOP实现事务的织入--> <!--配置事务通知--> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <!--给哪些方法配置事务--> <tx:attributes> <tx:method name="selectAll"/> <tx:method name="insert"/> <tx:method name="delete"/> </tx:attributes> </tx:advice> <!--配置事务切入--> <aop:config> <aop:pointcut id="txPointcut" expression="execution(* com.alb.mapper.*.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/> </aop:config> </beans>
UserMapperImpl:
public class UserMapperImpl extends SqlSessionDaoSupport implements UserMapper { @Override public List<User> selectAll() { User user = new User(5, "Asaa", "111111"); UserMapper mapper = getSqlSession().getMapper(UserMapper.class); mapper.insert(user); mapper.delete(5); return getSqlSession().getMapper(UserMapper.class).selectAll(); } @Override public int insert(User user) { return getSqlSession().getMapper(UserMapper.class).insert(user); } @Override public int delete(int id) { return getSqlSession().getMapper(UserMapper.class).delete(id); } }
测试类:
public class MyTes { @Test public void test(){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserMapper userMapper = context.getBean("userMapper", UserMapper.class); for (User user : userMapper.selectAll()) { System.out.println(user); } } }
注解式事务:
<!--只需在applicationContext.xml中加入以下内容即可--> <!--配置声明式事务--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <constructor-arg ref="dataSource"/> </bean> <!--开启注解式事务支持--> <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
UserServiceImpl:
// 在需要添加事务的方法或类上添加即可 @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class) @Override public List<User> selectAll() { User user = new User(5, "Asaa", "111111"); UserMapper mapper = getSqlSession().getMapper(UserMapper.class); mapper.insert(user); mapper.delete(5); return getSqlSession().getMapper(UserMapper.class).selectAll(); }
为什么需要事务?
- 如果不配置事务,可能存在数据提交不一致的情况
- 如果我们不在spring中去配置声明式事务,我们就需要在代码中手动配置事务
- 事务在项目开发中极为重要,涉及到数据的一致性和完整性问题