Spring的事务

使用Spring事务的两种方式

spring使用事务有两种方式:编程式事务(自己写代码)和声明式事务(注解)
注意: 关于编程式事务,一般用得很少,因为事务的代码会散落在我们的逻辑代码中,如果你真的想要使用编程式事务,就得使用TransactionTemplate

编程式事务

声明式事务

Spring中的声明式事务其实是通过AOP实现的,通过Spring官网的一张图可以看到AOP代理的过程

声明式事务的代码

PlatformTransactionManager

接口,主要实现事务的提交回滚

1
2
3
4
5
6
7
8
public 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,不管事务的回滚只看当前方法是否发生异常