使用Spring事务的两种方式
spring使用事务有两种方式:编程式事务(自己写代码)和声明式事务(注解)
注意: 关于编程式事务,一般用得很少,因为事务的代码会散落在我们的逻辑代码中,如果你真的想要使用编程式事务,就得使用TransactionTemplate
编程式事务
声明式事务
Spring中的声明式事务其实是通过AOP实现的,通过Spring官网的一张图可以看到AOP代理的过程
声明式事务的代码
PlatformTransactionManager
接口,主要实现事务的提交回滚1
2
3
4
5
6
7
8public interface PlatformTransactionManager {
TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;
void commit(TransactionStatus status) throws TransactionException;
void rollback(TransactionStatus status) throws TransactionException;
}
PlatformTransactionManager需要引入数据源DataSource(一般SpringBoot会自动帮你解决),我们用的最多的TransactionManager是DataSourceTransactionManager,它是JDBC包下(还有其他的,比如Hibernate或者JTA的)
TransactionStatus
接口,标明事务的状态,比如是否为可读,控制事务的执行
TransactionDefinition
接口,标明事务的定义,比如事务的传播性、隔离性、timeout、可读性..
TransactionAttribute
接口,获取@Transactional注解的value值、rollbackOn,然后添加进TransactionDefintion
@Transactional
注解,可以在类、接口、方法上注解,表示该类或方法需要事务代理
该注解的属性详解:
事务的特性
- 1、传播性
- 2、隔离性
- 3、超时性
- 4、只读性
事务的传播性
总共七种,但Spring官方文档只给出了三种,就是下面的三种:PROPAGATION_REQUIRED、PROPAGATION_REQUIRES_NEW、PROPAGATION_NESTED
PROPAGATION_REQUIRED
PROPAGATION_REQUIRES_NEW
PROPAGATION_NESTED
虽然跟REQUIRES_NEW差不多,也是再起一个事务,但是两个事务之间是有关联的,外部事务发生回滚时,内部事务也要回滚,但是内部事务发生回滚时,外部事务不用回滚(简单理解就是:外部最大)
七种:
事务的隔离性:
关于REQUIRES_NEW与NESTED事务传播特性的说明
比如有一段代码
一个事务方法里面调用另一个事务的方法,如果内部事务为NESTED,外部事务发生异常回滚时,内部事务也要回滚,但是内部事务发生回滚时,外部事务不需要回滚
如果内部事务为REQUIRES_NEW,不管事务的回滚只看当前方法是否发生异常