1. 什么是事物
- 事务是数据库操作最基本单元,逻辑上一组操作,要么都成功,如果有一个失败所有操作都失败。
- 典型场景:银行转账 ,lucy 转账 100 元 给 mary,lucy 少 100,mary 多 100 。
- 事务四个特性(ACID)
(1)原子性
(2)一致性
(3)隔离性
(4)持久性
2. 事物隔离级别
- 事务有特性成为隔离性,多事务操作之间不会产生影响。不考虑隔离性产生很多问题。
- 有三个读问题:脏读、不可重复读、虚(幻)读
- 脏读:一个未提交事务读取到另一个未提交事务的数据。
- 不可重复读:一个未提交事务读取到另一提交事务修改数据 。
- 虚读:一个未提交事务读取到另一提交事务添加数据 。
- 为了解决以上三个问题,就用不同的隔离级别:
3. 事物传播行为
- 事物传播就是在一个事物中调用另外的方法(事物)会产生什么样的行为。是新开启事物?还是同一个事物?还是没有事物?
4. 具体实现
spring中的事物的实现分为两种,一种是编程式事务管理,一种是声明式事务管理(使用) ,声明式事物是通过aop的原理进行实现的。
4.1 开起事务(配置形式)
<!--1 创建事务管理器-->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--注入数据源-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--2 配置通知-->
<tx:advice id="txadvice">
<!--配置事务参数-->
<tx:attributes>
<!--指定哪种规则的方法上面添加事务-->
<tx:method name="accountMoney" propagation="REQUIRED"/>
<!--<tx:method name="account*"/>-->
</tx:attributes>
</tx:advice>
<!--3 配置切入点和切面-->
<aop:config>
<!--配置切入点-->
<aop:pointcut id="pt" expression="execution(* com.spring5.service.UserService.*(..))"/>
<!--配置切面-->
<aop:advisor advice-ref="txadvice" pointcut-ref="pt"/>
</aop:config>
4.2 开起事务(注解形式,推荐)
//1、创建配置类,使用配置类替代 xml 配置文件
@Configuration //配置类
@ComponentScan(basePackages = "com") //组件扫描
@EnableTransactionManagement //开启事务
public class TxConfig {
//创建数据库连接池
@Bean
public DruidDataSource getDruidDataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql:///user_db");
dataSource.setUsername("root");
dataSource.setPassword("root");
return dataSource;
}
//创建JdbcTemplate对象
@Bean
public JdbcTemplate getJdbcTemplate(DataSource dataSource) {
//到ioc容器中根据类型找到 dataSource
JdbcTemplate jdbcTemplate = new JdbcTemplate();
//注入dataSource
jdbcTemplate.setDataSource(dataSource);
return jdbcTemplate;
}
//创建事务管理器
@Bean
public DataSourceTransactionManager getDataSourceTransactionManager(DataSource dataSource) {
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
transactionManager.setDataSource(dataSource);
return transactionManager;
}
}
@Service
// 事务超时,事务回滚等请自行查阅
@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.REPEATABLE.READ)
public class UserService {
// @Transactional也可以作用在方法上
}