Spring~事务API、事务失效原因、事务传播特性

Spring事务

Spring事务是在所使用的数据库事务的基础上进行封装扩展
封装主要是封装了一些JDBC的一写事务操作的对象, 扩展主要有以下几点特性

  1. 加入了事务传播的概念, 从代码逻辑上看来比编程式事务简化很多
  2. 提供声明式事务或者是注解式配置事务,让业务代码与事务分离,事务变得更易用(AOP技术)

但是也造成了事务失效的情况出现, 具体原因下面讲述

事务API

Spring提供了一个TransactionDefinition, 它定义了事务的隔离级别和传播特性
在这里插入图片描述
隔离级别默认是DEFAULT也就是默认是数据库的隔离级别

传播特性默认是required表示有就加入没有就创建

还专门定义了一个事务管理器PlatformTransactionManager, 提供了事务的commit提交和rollback回滚操作, 还有获取此时事务状态的一个方法
在这里插入图片描述
事务的状态有以下几个
在这里插入图片描述
顾名思义吧, 比如是否是新建的事务, 是否已经提交, 是否已经回滚, 是否完成

还有一个最重要的TransactionInterceptor, 而TransactionInterceptor实现了MethodInterceptor, 表示方法拦截, 当我们要执行配置了事务的方法的时候就会进行方法的拦截,拦截到配置了事务的方法之后就会在TransactionAspectSupport下, 对其信息一些加强处理(AOP)
在这里插入图片描述
大多情况使用注解**@Transactional**实现事务支持的话很方便, 可以配置一些属性

  1. name
    当在配置文件中有多个TransactionManager,可以用该属性指定选择哪个事务管理器。

  2. propagation
    事务的传播行为,默认值为 REQUIRED。

  3. isolation
    事务的隔离度,默认值采用DEFAULT。

  4. timeout
    事务的超时时间,默认值为-1。如果超过该时间限制但事务还没有完成,则自动回滚事务。

  5. read-only
    指定事务是否为只读事务,默认值为false;为了忽略那些不需要事务的方法,比如读取数据,可以设置read-only为true。

  6. rollback-for
    用于指定能够触发事务回滚的异常类型,如果有多个异常类型需要指定,各类型之间可以通过逗号分隔。

  7. no-rollback-for
    抛出no-rollback-for指定的异常类型,不回滚事务。

实现原理

这个的实现原理还是动态代理的方式实现, 基于CGLib动态代理, 核心就是使用拦截器。它就是TransactionInterceptor。

TransactionInterceptor实现了MethodInterceptor, 所以被@Transactional注解的方法会被TransactionInterceptor拦截, 然后invoke方法被调用根据@Transactional配置的属性初始化TransactionDefinition, TransactionManager会更具属性的判断是get还是new一个这个就是根据事务的传播特性去查, TransactionManager有个方法就是为了获得此时事务的状态, 也可以方便去判断是,最终会调用TransactionAspectSupport方法实现增强.

事务失效

bean是否被Spring托管, 或者Bean是否被代理

方法是否是public的

数据库是否支持事务

方法是不是被static或者final修饰

是否是方法内部调用导致的事务失效

异常是否被catch了

异常是否符合规范, 默认是runtimeException

事务传播机制

在这里插入图片描述

  • 常用的事务传播机制

PROPAGATION_REQUIRED
这个也是默认的传播机制;

PROPAGATION_REQUIRES_NEW
总是新启一个事务,这个传播机制适用于不受父方法事务影响的操作
比如某些业务场景下需要记录业务日志,用于异步反查,那么不管主体业务逻辑是否完成,日志都需要记录下来,不能因为主体业务逻辑报错而丢失日志;

PROPAGATION_NOT_SUPPORTED
不使用事务, 有事务就挂起
可以用于发送提示消息,站递信、短信、邮件提示等。不属于并且不应当影响主体业务逻辑,即使发送失败也不应该对主体业务逻辑回滚。

猜你喜欢

转载自blog.csdn.net/Shangxingya/article/details/114193700
今日推荐