• Spring 事务相关



    聊过了 MySQL 事务相关内容,来看看spring 事务有关内容吧。我们都知道在 spring 中用 @Transaction 来管理事务,那它里面的属性是什么意思呢,还有其他方式来管理事务吗

    编程式事务

    除了使用注解这个声明式事务来管理事务外,还有编程式事务管理方式,通过 TransactionTemplate 或者 TransactionManager 手动管理事务,实际应用中很少使用

    调用 TransactionTemplate 的 execute 方法来执行事务,传入一个 TransactionCallbackWithoutResult 对象

    @Resource
    private TransactionTemplate transactionTemplate;
    public void test() {
    
            transactionTemplate.execute(new TransactionCallbackWithoutResult() {
                @Override
                protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                    try {
                        // ....  
                    } catch (Exception e){
                        //回滚
                        transactionStatus.setRollbackOnly();
                    }
                }
            });
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    还有一个调用 TransactionManager 的 getTransaction 方法,这里就不写了

    事务的隔离级别

    一共五种隔离级别,使用 isolation(隔离)属性来配置

    四种隔离级别与MySQL的隔离级别相同,分别是读未执行,读已执行,不可重复读,串行化

    另外一种是默认隔离级别,使用后端数据库默认的隔离级别

    事务传播行为

    指服务层的事务方法之间互相调用时会发生什么

    使用propagation(交易)来配置传播行为,一共有七种传播行为

    public interface TransactionDefinition {
        int PROPAGATION_REQUIRED = 0;
        int PROPAGATION_SUPPORTS = 1;
        int PROPAGATION_MANDATORY = 2;
        int PROPAGATION_REQUIRES_NEW = 3;
        int PROPAGATION_NOT_SUPPORTED = 4;
        int PROPAGATION_NEVER = 5;
        int PROPAGATION_NESTED = 6;
        ......
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    Spring 为了方便使用,定义了一个枚举类:Propagation,虽然不知道这个枚举类方便在哪里

    package org.springframework.transaction.annotation;
    
    import org.springframework.transaction.TransactionDefinition;
    
    public enum Propagation {
    
        REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED),
    
        SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS),
    
        MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY),
    
        REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW),
    
        NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED),
    
        NEVER(TransactionDefinition.PROPAGATION_NEVER),
    
        NESTED(TransactionDefinition.PROPAGATION_NESTED);
    
        private final int value;
    
        Propagation(int value) {
            this.value = value;
        }
    
        public int value() {
            return this.value;
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    支持外围事务的情况:

    1,PROPAGATION_REQUIRED: 如果当前存在事务,则加入该事务;如果当前没有事务,创建一个新事务,这个是默认的,并且也使用的最多

    举个例子,当两个方法都用这个传播行为,a 调用 b,此时b中的行为加入a,形成同一个事务,此时b中错误出现回滚a也跟这回滚;a如果是一个普通方法,调用事务方法b,此时b生成一个新事务干自己的事情

    2,PROPAGATION_SUPPORTS: 如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行

    3,PROPAGATION_MANDATORY: 如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常

    不支持外围事务:

    1,PROPAGATION_REQUIRES_NEW: 创建一个新的事务,如果当前存在事务,则把当前事务挂起

    听说过线程挂起听说过事务挂起吗?当事务创建时,就会被绑定到一个线程上。该线程会伴随着事务整个生命周期,直到事务提交、回滚或挂起(临时解绑)。线程和事务的关系是1:1,当线程绑定了一个事务后,其他事务不可以再绑定该线程,反之亦然

    了解事务和线程的关系,也很容易理解事务挂起。对事务的配置在Spring内部会被封装资源(Resource),线程绑定了事务,自然也绑定了事务相关的资源。挂起事务时,把这些资源取出临时存储,等待执行完成后,把之前临时存储的资源重新绑定到该线程上

    这种情形下,事务a调用事务b,a在b执行完后发生异常,b不会回滚,但是如果b抛出异常,a会回滚

    2,PROPAGATION_NOT_SUPPORTED: 以非事务方式运行,如果当前存在事务,则把当前事务挂起

    3,PROPAGATION_NEVER: 以非事务方式运行,如果当前存在事务,则抛出异常

    其他情况:

    PROPAGATION_NESTED: 如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,创建一个事务。如果 b 回滚的话,a 也会回滚

    事务超时属性

    所谓事务超时,就是指一个事务所允许执行的最长时间,如果超过该时间限制但事务还没有完成,则自动回滚事务。在 TransactionDefinition 中以 int 的值来表示超时时间,其单位是秒,默认值为-1,这表示事务的超时时间取决于底层事务系统或者没有超时时间

    Spring AOP 自调用问题

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

    这是由于Spring AOP代理的原因造成的,因为只有当 @Transactional 注解的方法在类以外被调用的时候,Spring 事务管理才生效。

  • 相关阅读:
    LeetCode:1334. 阈值距离内邻居最少的城市(Floyd C++)
    大于10M图片如何查看?
    消费者偏移量_consumer_offsets相关解析
    算法通关村第十二关——字符串反转问题解析
    如何低成本的玩转独立站
    AI:74-基于深度学习的宠物品种识别
    双臂二指魔方机器人的制作(三)--还原控制
    Meetup 回顾|Data Infra 研究社第十六期(含资料发布)
    双调旅行商问题
    Hadoop实战——MapReduce-字符统计(超详细教学,算法分析)
  • 原文地址:https://blog.csdn.net/sekever/article/details/126212384