spring事务传播机制使用及原理

2023-11-09

事务

**事务是逻辑上的一组操作,要么都执行,要么都不执行。**事务的四大特性 :

原子性,构成事务的所有操作,要么都执行完成,要么全部不执行,不可能出现部分成功部分失 败的情况。

一致性,在事务执行前后,数据库的一致性约束没有被破坏。

隔离性,数据库中的事务一般都是并发的,隔离性是指并发的两个事务的执行互不干扰,一个事 务不能看到其他事务运行过程的中间状态。

持久性,事务完成之后,该事务对数据的更改会被持久化到数据库,且不会被回滚。

spring编程式事务管理

手动管理事务,通过spring的 TransactionTemplate、transactionManager或者mybatis的sqlsession手动管理事务,变成控制事务提交和回滚,实际应用中很少使用。

@Autowired
private PlatformTransactionManager transactionManager;

public void testTransaction() {

  TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
          try {
               // ....  业务代码
              transactionManager.commit(status);
          } catch (Exception e) {
              transactionManager.rollback(status);
          }
}

spring声明式事务管理

声明式事务管理可以使用aop txadvice 配置类,也可以使用xml aop配置,还可以基于@Transactional 的注解,该方式使用最多,因为@Transactional可以用在方法上,颗粒度更细。三者的原理上都是一致的,利用spring aop原理,注入动态代理类,调用事务拦截器TransactionInterceptor,数据的提交会设置成手动提交,来进行事务传播管理。

@Configuration
public class TxAnoConfig {

  
    @Autowired
    private DataSource dataSource;

    @Bean("txManager")
    public DataSourceTransactionManager txManager() {
        return new DataSourceTransactionManager(dataSource);
    }

    /*事务拦截器*/
    @Bean("txAdvice")
    public TransactionInterceptor txAdvice(DataSourceTransactionManager txManager){
        NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();
          /*只读事务,不做更新操作*/
         RuleBasedTransactionAttribute readOnlyTx = new RuleBasedTransactionAttribute();
         readOnlyTx.setReadOnly(true);
         readOnlyTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED );
         RuleBasedTransactionAttribute requiredTx = new RuleBasedTransactionAttribute(TransactionDefinition.PROPAGATION_REQUIRED,
             Collections.singletonList(new RollbackRuleAttribute(Exception.class)));
         requiredTx.setTimeout(5);
         Map<String, TransactionAttribute> txMap = new HashMap<>();
         txMap.put("add*", requiredTx);
         txMap.put("save*", requiredTx);
         txMap.put("insert*", requiredTx);
         txMap.put("update*", requiredTx);
         txMap.put("delete*", requiredTx);
         txMap.put("get*", readOnlyTx);
         txMap.put("query*", readOnlyTx);
         txMap.put("select*", readOnlyTx);
         source.setNameMap( txMap );
        return new TransactionInterceptor(txManager ,source) ;
    }
 
    /**切面拦截规则 参数会自动从容器中注入*/
    @Bean
    public DefaultPointcutAdvisor defaultPointcutAdvisor(TransactionInterceptor txAdvice){
        DefaultPointcutAdvisor pointcutAdvisor = new DefaultPointcutAdvisor();
        pointcutAdvisor.setAdvice(txAdvice);
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression("execution (* com.*.*.service.order.*.*(..))");
        pointcutAdvisor.setPointcut(pointcut);
        return pointcutAdvisor;
    }
 
 
}
<?xml version="1.0" encoding="UTF-8"?>

<beans  xmlns="http://www.springframework.org/schema/beans"
		......

        http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

    <bean id="txManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 使用tx标签配置的拦截器 -->

    <!-- 定义事务 -->

    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <tx:method name="query*" propagation="SUPPORTS" read-only="true"/>
            <tx:method name="get*" propagation="SUPPORTS" read-only="true"/>
            <tx:method name="select*" propagation="SUPPORTS" read-only="true"/>
            <tx:method name="*" propagation="REQUIRED" rollback-for="Exception"/>
        </tx:attributes>
    </tx:advice>

    <!-- 定义切面 -->

    <aop:config>

        <aop:pointcut id="interceptorPointcut" expression="execution (* com.*.*.service.order.*.*(..))" />

        <aop:advisor advice-ref="txAdvice" pointcut-ref="interceptorPointcut" order="0"/>

    </aop:config>

</beans>

@Transactional 和AOP 配置类或者XML配置都存在时,两者的aop拦截器都会注册,根据注册顺序来定义方法的事务属性,后面的会覆盖前面的,一般来说注解类的会覆盖配置类的事务定义。

事务管理类

Spring 框架中,事务管理相关最重要的 3 个接口如下:

PlatformTransactionManager: (平台)事务管理器,Spring 事务策略的核心,数据源连接,事务的管理者。
TransactionDefinition: 事务定义信息(事务隔离级别、传播行为、超时、只读、回滚规则)。
TransactionStatus:事务运行状态
TransactionSynchronizationManager :事务后置处理,使用ThreadLocal来为不同的事务线程提供独立的资源副本,并且同时维护这些事务的配置属性和运行状态。

PlatformTransactionManager提供了数据源的连接池的连接,可以重中获取连接不同平台的数据库连接实例,Spring 为各个平台如 JDBC(DataSourceTransactionManager)、Hibernate(HibernateTransactionManager)、JPA(JpaTransactionManager)等都提供了对应的事务管理器,PlatformTransactionManager 会根据 TransactionDefinition 的定义比如事务超时时间、隔s离级别、传播行为等来进行事务管理 ,而 TransactionStatus 接口则提供了一些方法来获取事务相应的状态比如是否新事务、是否可以回滚等等。

在这里插入图片描述

事务传播行为

所谓事务的传播行为是指,如果在开始当前事务之前,一个事务上下文已经存在,此时有若干选项可以指定一个事务性方法的执行行为。在TransactionDefinition定义中包括了如下几个表示传播行为的常量:

TransactionDefinition.PROPAGATION_REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。这是默认值。一个事务,要么成功,要么失败。
TransactionDefinition.PROPAGATION_REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则把当前事务挂起。两个不同事务,彼此之间没有关系。一个事务失败了不影响另一个事务。
TransactionDefinition.PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起。
TransactionDefinition.PROPAGATION_NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。
TransactionDefinition.PROPAGATION_MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
TransactionDefinition.PROPAGATION_NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。

事务隔离级别

隔离级别是指若干个并发的事务之间的隔离程度。TransactionDefinition 接口中定义了五个表示隔离级别的常量:

TransactionDefinition.ISOLATION_DEFAULT:这是默认值,表示使用底层数据库的默认隔离级别。对大部分数据库而言,通常这值就是TransactionDefinition.ISOLATION_READ_COMMITTED。
TransactionDefinition.ISOLATION_READ_UNCOMMITTED:该隔离级别表示一个事务可以读取另一个事务修改但还没有提交的数据。该级别不能防止脏读,不可重复读和幻读,因此很少使用该隔离级别。
TransactionDefinition.ISOLATION_READ_COMMITTED:该隔离级别表示一个事务只能读取另一个事务已经提交的数据。该级别可以防止脏读,没有行锁,这也是大多数情况下的推荐值。
TransactionDefinition.ISOLATION_REPEATABLE_READ:该隔离级别表示一个事务在整个过程中可以多次重复执行某个查询,并且每次返回的记录都相同。该级别可以防止脏读和不可重复读。但是可能出现幻像读。原因是开了行锁,禁止了事务开启期间修改内容,不影响继续新增行,所以还是会幻读。
TransactionDefinition.ISOLATION_SERIALIZABLE:所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。

事务超时

所谓事务超时,就是指一个事务所允许执行的最长时间,如果超过该时间限制但事务还没有完成,则自动回滚事务。在 TransactionDefinition 中以 int 的值来表示超时时间,其单位是秒。
默认设置为底层事务系统的超时值,如果底层数据库事务系统没有设置超时值,那么就是none,没有超时限制。

事务只读属性

只读事务用于客户代码只读但不修改数据的情形,修改数据会会报错,SET TRANSACTION READ ONLY类似于SERIALIZABLE事务隔离级别,在发布SET TRANSACTION READONLY起的所有SELECT语句,其结果均为同一个时间点一致,直至显式地发布了COMMIT或ROLLBACK命令或隐式提交(执行DDL)。只读事务用于特定情景下的优化,适合用在有多条数据库查询操作的方法中,保证读取事务数据一致性。

事务回滚规则

@Transactional(rollbackFor= MyException.class),定义了哪些异常会导致事务回滚而。默认情况下**,事务只有遇到运行期异常(RuntimeException 的子类)时才会回滚,Error 也会导致事务回滚,但是,在遇到检查型(Checked)异常时不会回滚。**

spring事务使用常见问题

  1. 如果同一个类中的其他没有@Transactional注解的方法内部调用有@Transactional 注解的方法,有@Transactional 注解的方法的事务会失效。

    Spring AOP代理的原因造成的,因为只有当 @Transactional 注解的方法在类以外被调用的时候,Spring 事务管理才生效。换句话说当执行一个类中的普通方法时,Spring没有生成代理对象,即使这个方法内部调用了同类其他的事务方法,也就无法参与事务管理了。

  2. A类的事务方法中调用了B类的事务方法,B方法发生了异常,但是在A类的try-catch模块中捕获了这个异常并正常执行,“Transaction rolled back because it has been marked as rollback-only”

    B方法发生了异常,给当前事务打上了rollbackOnly标记,但是被A捕获到了并正常执行,由于只有一个事务,等到A方法要提交这一个事务的时候,没有发现异常但是发现事务被打上了rollbackOnly,只能回滚并抛出一个unexpectedRollback异常。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

spring事务传播机制使用及原理 的相关文章

随机推荐

  • 解决从GitHub下载文件时缓慢的问题

    我们知道 访问GitHub在国内的速度还算过得去 但是从GitHub上下载文件的速度就非常慢了 以下方法就是为了解决下载速度缓慢的 截止2019 9 5前测试有效 1 用记事本打开hosts文件 路径为C Windows System32
  • Mysql 实践(一):部署和安装

    1 目标 卸载centos自带的mysql 安装mysql 5 6 33 2 步骤 1 下载mysql 下载地址 http dev mysql com downloads mysql 5 6 html downloads 我们下载 这些包
  • 基于SSM框架的实验室开放管理系统

    系统功能结构设计 在分析并得出使用者对程序的功能要求时 就可以进行程序设计了 管理员功能结构图 管理员主要负责填充图书和其类别信息 并对已填充的数据进行维护 包括修改与删除 管理员也需要审核老师注册信息 发布公告信息 管理自助租房信息等 用
  • flutter初学之悬浮按钮

    期望 想实现一个悬浮在整个页面的悬浮按钮 实现1 用FloatingActionButton实现 新增悬浮按钮 Widget createFixedAddWidget ProductEntryState state Dispatch dis
  • linux环境下查看因内存占用过大被杀掉的进程

    文章目录 前言 查询方法 通过系统日志查找 通过dmesg命令查找 进程被杀的原因 总结 前言 最近发生两次游戏服务器进程突然消失的事件 查询日志上下文没有找到有用的信息 日志显示运行到某处戛然而止 此处代码逻辑简单 排除异常逻辑导致的服务
  • data_support/utlist(关于编译器的一些宏宏设置)

    ifndef UTLIST H tlist 权限查看程序 define UTLIST H define UTLIST VERSION 1 9 8 include
  • 灰度图像直方图均衡化公式及实现

    图像的直方图 直方图是图像中像素强度分布的图形表达方式 它统计了每一个强度值所具有的像素个数 直方图均衡化 是通过拉伸像素强度分布范围来增强图像对比度的一种方法 是图像处理领域中利用图像直方图对对比度进行调整的方法 均衡化指的是把一个分布
  • 华为手机发展史

    一 成立手机业务部 大家好 我是小码哥 今天我们来聊一下华为手机的发展史 作为国内乃至世界技术成熟大型互联网企业 已经成为国内市场不可缺失的一部分 华为由任正非在1987年创办的 至今已有34年 华为最初是做交换机起家 随着互联网的发展 华
  • 对象数组(初学)

    目录 一 什么是对象数组 二 定义对象数组 三 对象数组初始化 四 访问对象数组元素 五 new和对象数组 一 什么是对象数组 所谓对象数组 指每一个数组元素都是对象的数组 即若一个类有若干个对象 把这一系列的对象用一个数组来存放 对象数组
  • 关闭httpclient4.5控制台日志输出

    httpclient4 5每次执行的时候都会在控制台输出大量日志 一般情况下并不需要 去官方看了 没找到去掉日志的方法 囧 官网链接 https hc apache org httpcomponents client 4 5 x loggi
  • 2020-09-07

    使 mqtt fx连阿 云时 直提 MQTTException 最近在搞一个Mqtt项目 在用mqtt fx工具做测试时怎么都连接不上阿里云 直提 MQTTException 记得之前也都是可能的 操作好像都是按照官方的文档来操作的 密码也
  • RX8025T RTC读写与秒中断

    目录 一 精度 二 读写时序 三 写RTC对其内部ms计数的影响 四 在FPGA中用GPS校正RTC 五 ms维护 六 IIC防锁死计数清零 七 日期计算星期公式 一 精度 二 读写时序 接口为IIC 读写时序如下图 注意 1 写操作 写从
  • PHP常见问题总结

    1 为什么会出现这种情况 端口什么的都设置正确了 解决方法 请将本机的IIS服务关闭 开启Apache服务 IIS服务的关闭方法可参见 https jingyan baidu com article 0f5fb099e0d7216d8334
  • 理解JPEG文件头的格式

    1 JPEG 1 why jpeg jpeg作为图片传输格式使用最为普遍 压缩比最高 每天我们都会产出和传输大量的jpeg格式数据 手机拍出来的格式默认是jpeg 朋友圈各种分享 磁盘上积累了大量的jpeg 因此本人一直对jpeg头部数据非
  • CLIP:创建图像分类器

    介绍 假设需要对人们是否戴眼镜进行分类 但是没有数据或资源训练自定义模型 在本教程中 你将学习如何使用预训练的CLIP模型创建自定义分类器 无需任何训练 这种方法称为零快照图像分类 它使得能够对在原始CLIP模型训练期间未明确观察到的的类进
  • 并发基础知识(二)[进程间通信·信号]

    1 信号 信号是进程间通信的一种方式 这种方式没有数据传输 只是在内核中传递一个信号 整数 信号的表示是一个整数 不同的信号值 代表不同的含义 当然用户可以自定义信号 那么自定义的信号的含义和值由程序员来定和解释 Term Terminat
  • DVWA-15.Open HTTP Redirect

    OWASP将其定义为 当 Web 应用程序接受不受信任的输入时 可能会导致 Web 应用程序将请求重定向到不受信任输入中包含的 URL 则可能会出现未经验证的重定向和转发 通过修改恶意站点的不受信任的 URL 输入 攻击者可以成功发起网络钓
  • OpenGL ES基本流程总结

    作为一个学习总结 绘制了OpenGL ES中完成一次渲染所需要的一些基本步骤 离屏渲染 此处是以离屏渲染为例 离屏渲染是不直接上屏的 而是渲染到缓冲区中 那么这块缓冲区就需要我们手动创建 也就是上图所示的Framebuffer 其中需要三个
  • 车载以太网入门

    车载以太网入门 以太网的首要优势之一在于支持多种网络介质 因此可以在汽车领域进行使用 同时由于物理介质与协议无关 因此可以在汽车领域可以做相应的调整与拓展 形成一整套车载以太网协议 该协议将会在未来不断发展并长期使用 车载以太网总体架构 正
  • spring事务传播机制使用及原理

    事务 事务是逻辑上的一组操作 要么都执行 要么都不执行 事务的四大特性 原子性 构成事务的所有操作 要么都执行完成 要么全部不执行 不可能出现部分成功部分失 败的情况 一致性 在事务执行前后 数据库的一致性约束没有被破坏 隔离性 数据库中的