尚硅谷spring框架视频教程——学习笔记二(数据库、事务、webflux)
目录
- 一、数据库操作
- 二、事务操作
- 1. 事务的四个特性
- 2. 事务的底层逻辑
- 3. 注意事项
- 4. 启动事务操作
- 5. 事务传播行为(propagation)
- 6. 事务隔离级别
- 7. 其他配置
- 三、Spring5新功能——webflux
一、数据库操作
spring框架使用JDBCTemplate对JDBC(java数据库连接,java database connectivity)进行封装,方便实现数据库操作。
JDBCTemplate使用步骤:
- 在配置文件中配置数据库连接池DruidDataSource,bean属性包括url、用户名、密码等(可改成配置类,使用@Bean注解,方法中直接new对象);
- 在配置文件中将DruidDataSource注入JDBCTemplate(可改成配置类,使用@Bean注解,方法中直接new对象);
- 在dao中注入JDBCTemplate(使用@Autowired等注解);
- 调用JDBCTemplate的方法。在Springboot里不会直接调用JDBCTemplate的方法,所以没仔细看。
完全注解开发:
@Configuration
@ComponentScan(basePackages = "com.xxx")
public class JdbcConfig {
// 将类交给Spring管理
@Bean
public DruidDataSource getDruidDataSource() {
DruidDataSource dataSource = new DruidDataSource();
// 省略设置属性代码
return dataSource;
}
@Bean
// 到ioc容器中,根据类型找到dataSource
public JdbcTemplate getJdbcTemplate(DruidDataSource dataSource) {
JdbcTemplate jdbcTemplate = new JdbcTemplate();
jdbcTemplate.setDataSource(dataSource);
return jdbcTemplate;
}
}
二、事务操作
事务是逻辑上的一组操作,被视为不可分割的基本单位。典型事务场景——银行转账:一个账户的钱增加,另一个账户的钱减少,这两个操作要么都成功,要么都失败。
1. 事务的四个特性
- 原子性(Atomicity):事务操作不可分割,要么都成功,要么都失败;
- 一致性(Consistency):操作前后数据库状态保持一致,比如转账的场景要求金额总量不变;
- 隔离性(Isolation):多个事务操作同一张表时,不会相互影响;
- 持久性(Durability):提交后,数据库中数据的改变是持久的;
2. 事务的底层逻辑
Spring框架底层通过使用AOP进行事务管理。
增强的逻辑为:
(1)开启事务;
(2)调用被代理的方法,进行业务操作;
(3)没有异常,提交事务;
(4)出现异常,事务回滚;
具体原理:
如果我们开启了事务,会注册一个BeanPostProcesser(bean后置处理器)的实现类到容器中, 这个BeanPostProcesser会在postProcessAfterInitialization方法中使用代理类来偷梁换柱真正的bean。
其中,bean后置处理器的postProcessAfterInitialization方法在bean初始化完成后被调用。
更详细的原理解释可以看这篇文章 Spring的AOP原理 – 事务自调用失效和public字段不能直接访问
3. 注意事项
由于事务是通过代理实现的,所以在使用事务时需要注意一些事项:
- 类内方法调用,事务不生效
同一个类内,方法A调用方法B,如果A没开启事务,即使B开启了事务,事务也不会生效。这时因为调用代理类的方法才能开启事务,而类内方法调用时,调用的不是代理类的方法。 - 方法使用final修饰,事务不生效
因为代理类无法对final方法进行重写。 - 加在public方法上的事务注解才会生效
因为外部类只能看见public修饰的方法,而上面提到了,类内调用事务不生效。
另外还需要注意,事务涉及的操作要尽可能的少,避免大事务,否则可能会引起数据库连接池占满、接口超时、回滚时间长等问题。
更多的注意实现可以参照这篇文章Spring事务失效的场景
4. 启动事务操作
使用注解方式开启事务:
- 在配置文件中创建事务管理器DataSourceTransactionManager的bean实例,并注入datasource;
- 使用tx命名空间,在配置文件中开启事务注解,并指定事务管理器(完全注解开发可在配置类中使用@EnableTransactionManagement注解实现);
- 在方法上加@Transactional,也可以加到类上,这时会对类的所有方法都加上事务注解;
5. 事务传播行为(propagation)
事务传播行为表示当一个事务方法被另一个事务方法调用时,这个事务该如何进行。总共有7种行为,常用的3个是:
- REQUIRED:如果有事务在运行,当前方法在这个事务内运行;否则,启动一个新的事务,并在自己的事务内运行,这是默认的传播属性。
- REQUIRES_NEW:当前方法必须启动新事务,并在它自己的事务内运行,同时将正在运行的事务挂起,执行完当前新建是事务以后,挂起的事务再恢复执行。
- SUPPORTS:如果有事务正在运行,当前方法在事务内运行,否则使用非事务的方法运行。
6. 事务隔离级别
事务隔离级别考虑的是如何减少多事务操作之间的互相影响。
(1)不考虑事务之间的相互影响会导致的问题
- 脏读:一个未提交事务读取了另一个未提交事务中的数据。比如,B的转账事务还未提交,A已经可以查询到数据库里的钱增加;
- 不可重复读:一个未提交事务读取到另一个提交事务的数据。这是由于在事务的两次查询间隔中,数据被另一个事务修改并提交了,导致多次查询返回了不同的结果;
- 虚读(幻读):一个未提交事务读取到另一个提交事务添加/删除的数据,导致查询到的数据量不一致;
(2)设置事务的隔离级别
- Read uncommitted (读未提交):最低级别,任何情况都无法保证。
- Read committed (读已提交):可避免脏读的发生。
- Repeatable read (可重复读):可避免脏读、不可重复读的发生。是MySQL的默认隔离级别。
- Serializable (串行化):可避免脏读、不可重复读、幻读的发生。
更详细的内容可查看这篇文章数据库的事务四大特性(ACID)、详解隔离性以及隔离级别、锁
7. 其他配置
- timeout:超时时间,如果事务没有在一定时间内提交,就会进行回滚。默认值是-1,表示不设置超时时间;单位是秒
- readOnly:是否只读,为true时只能做查询操作
- rollbackFor:指定异常进行回滚
- noRollbackFor:指定异常不进行回滚
三、Spring5新功能——webflux
webflux用于web开发,功能与SpringMVC类似,但用的是响应式编程的思想。它是一种异步非阻塞的框架,在servlet3.1以后才支持。
特点:
- 非阻塞,可以在有限的资源下,提高系统吞吐量和伸缩性,以Reactor为基础实现响应式编程。
响应式编程是基于观察者模式实现的,数据的变化通过流进行传播。比如Excel里的单元格表达式,如果改了其中一个单元格数值,包含公式的单元格会自动重新计算。 - Spring5基于Java8,Webflux使用Java8函数式编程方式实现路由请求。