问题十三:为什么要有事物传播行为?
问题十四:介 绍 一 下Spring的 事物管理
Spring 事务为何失效了
事务是执行逻辑的一组执行单元,要么都执行,要么都不执行
- 编程式事务
代码侵入性强
Spring事务三大接口
1. PlatformTransactionManager
平台事务管理器
模板方法设计模式,事务具体实现交给Hibernate等平台框架
数据访问技术 实现类 JDBC DataSourceTransactionManager JPA JpaTransactionManager Hibernate HibernateTransactionManager JDO JdoTransactionManager 分布式事务 JtaTransactionManager
2. TransactionDefinition
事务定义信息(隔离级别,传播行为,超时,只读,回滚规则)
- int getPropagationBehavior():事务的传播行为
- int getIsolationLevel():事务的隔离级别
- int getTimeout():事务的过期时间
- boolean isReadOnly():事务的读写特性
事务的传播行为
却是Spring凭借自身的框架提供的功能 ;
@Transactional(propagation=Propagation.REQUIRED)
Spring事务传播属性:
1.propagation=required: 支持当前有事务,就加入当前事务中;如果当前方法没有事务,就新建一个事务;
2.propagation=requires_new: 新建事务,如果当前存在事务,就把当前事务挂起;如果当前方法没有事务,就新建事务;
2.propagation=supports: 支持当前事务,如果有就加入当前事务中;如果当前方法没有事务,就以非事务的方式执行;
3.propagation=mandatory: 支持当前事务,如果有就加入当前事务中;如果当前没有事务,就抛出异常;
5.propagation=not-supported: 以非事务方式执行,如果当前方法存在事务就挂起当前事务;如果当前方法不存在事务,就以非事务方式执行;
6.propagation-never: 以非事务方式执行,如果当前方法存在事务就抛出异常;如果当前方法不存在事务,就以非事务方式执行;
7.propagation-nested: 如果当前方法有事务,则在嵌套事务内执行;如果当前方法没有事务,则与required操作类似;
前六个策略类似于EJB CMT,第七个(PROPAGATION_NESTED)是Spring所提供的一个特殊变量。
它要求事务管理器或者使用JDBC 3.0 Savepoint API提供嵌套事务行为(如Spring的DataSourceTransactionManager)
3. TransactionStatus
事务运行状态
声明式事务使用
声明式事务最大的优点就是不需要通过编程的方式管理事务,底层使用AOP实现
@Transactional不仅可以注解在方法上,也可以注解在类上。当注解在类上时,意味着此类的所有public方法都是开启事务的。
@Service
public class PersonService {
@Resource
private PersonMapper personMapper;
@Resource
private CompanyMapper companyMapper;
@Transactional(rollbackFor = {RuntimeException.class, Error.class})
public void saveOne(Person person) {
Company company = new Company();
company.setName("tenmao:" + person.getName());
companyMapper.insertOne(company);
personMapper.insertOne(person);
}
}
注解属性
- Propagation 传播行为
默认值为 Propagation.REQUIRED
- Isolation 隔离级别
默认是Isolation.DEFAULT
也就是数据库自身的默认隔离级别
- Timeout超时时间
时间内需要提交,否则回滚,默认-1(秒)
- rollbackFor:触发回滚的异常
默认是RuntimeException和Error
- noRollbackFor 不会滚
- readOnly
是否只读, true:只能查询
ps:
- 网络上还说要在
@SpringBootApplication
上添加注解@EnableTransactionManagement
,已经不需要了 - Spring的默认的事务规则是遇到运行异常(RuntimeException)和程序错误(Error)才会回滚。如果想针对非检测异常进行事务回滚,可以在@Transactional 注解里使用
- 手动回滚TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
作者:十毛tenmao 链接:https://www.jianshu.com/p/9b5eb43236cc
https://blog.csdn.net/xcbeyond/article/details/81235995