目录
1. 复习数据库事务
事务:用于保证组成事务的多个操作,要么一起成功,要么一起失败
使用的步骤:
-
开启事务:start transaction; 或者 begin
-
执行多条SQL语句。SQL语句不会立即生效,而是被暂时缓存起来
-
关闭事务:
-
提交事务:commit 事务里所有的操作将会全部、立即生效
-
回滚事务:rollback 事务里所有的操作将会全部、立即撤消
-
2. Spring事务入门
1 事务问题演示
-
准备事务的基础代码:以前边的tlias项目代码为基础
-
要求:删除部门的同时,也要删除部门里的员工
2 Spring事务入门
哪个方法需要放到同一个事务里,就在哪个方法上加注解@Transactional
3 Spring事务原理
Spring的事务管理,底层使用的是AOP技术
4 小结
哪个方法需要事务,就在哪个方法上加注解 @Transactional
Spring事务底层:使用了AOP技术实现的
3. @Transactional详解
注解@Transactional(rollbackFor=异常类名.class, propagation=传播行为)
两个常用的属性
1 rollbackFor事务回滚
默认情况,Spring的事务,只会在抓捕到RuntimeException
时,才会回滚
-
如果代码里抛出的不属于
RuntimeException
,事务将会失效
如果想要修改Spring的事务:指定的异常进行回滚:
-
@Transactional(rollbackFor=异常类名.class)
使用示例:
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteDeptById(Integer id) throws Exception {
//删除部门
deptMapper.deleteById(id);
// int i = 1/0;
//如果在页面上删除id为2的部门,代码会报异常。但是Spring的事务默认是不会抓捕这种异常的
if (id == 2) {
throw new Exception("人造异常");
}
//删除部门里的员工:delete from emp where dept_id = ?
empMapper.deleteByDeptId(id);
}
2 propagation事务传播行为
事务传播行为:业务方法调用业务方法时,事务的一致性问题
Spring配置传播行为:@Transactional(propagation=Propagation.传播行为)
可用的传播行为有:
-
REQUIRED:如果有事务就用;如果没有事务就开启新事务
-
SUPPORT:如果有事务就用;如果没有事务就以非事务方式执行
-
MANDATORY:如果有事务就用;如果没有事务就抛出异常
-
REQUIRES_NEW:如果有事务就挂起不用,而是开启新事务;如果没有事务就开启新事务
-
NOT_SUPPORTED:如果有事务就挂起不用,以非事务方式执行;如果没有事务,以非事务方式执行
-
NEVER:如果有事务就抛出异常;如果没有事务,就以非事务方式执行
-
NESTED:事务嵌套。如果有事务,就开启一个子事务;如果没有事务,就开启新事务
4. 事务失效的情况【面试】
正常情况下,哪个方法加了@Transactional注解,就有事务了
但是一些特殊情况,可能会事务失效:
-
方法是private。不允许加事务
-
类上没有加@Component或者@Service等等注解。类没有被Spring管理
-
同一个类里:一个非事务方法,通过this调用了事务方法,事务会失效
因为事务管理的代码,实质上是在AOP生成的代理对象里
同一类里通过this直接调用方法,不经过代理对象,所以没有事务效果
-
事务方法里的异常没有抛,而是try...catch了:★
比如事务方法里自己加了try...catch,异常没有抛出去
AOP的代理对象就抓不到异常,也就不会进行回滚
-
事务里抛的异常,不是RuntimeException
默认情况下,Spring的事务只抓取RuntimeException
如果抛的不是这种异常,事务AOP就抓不到异常,也就不会进行回滚