Spring事务传播机制

开发中有多个事务方法嵌套调用时,就涉及到了 Spring 的事务传播机制。

下面梳理一下 7 种传播机制的含义,做一些测试以加深理解,也方便开发中灵活使用。

1. Spring事务传播类型枚举Propagation

  • REQUIRED: 没有事务就开启,有事务就加入,不指定的话默认为该类型
  • SUPPORTS: 有事务就加入,没有就无事务运行
  • MANDATORY: 加入当前事务,如果不存在则抛出异常
  • REQUIRES_NEW: 没有就开启,有了挂起原来的,开启新的
  • NOT_SUPPORTED: 有了挂起,没有就无事务运行
  • NEVER: 以非事务方式执行,如果存在事务则抛出异常
  • NESTED: 如果当前事务存在,则在嵌套事务中执行,否则行为类似于REQUIRED

大多数情况下,用默认的 REQUIRED 就足够了,其它的用的较少。

2. 传播机制测试

2.1 测试准备

Spring Boot,JPA,Lombok,MySQL

建表:

CREATE TABLE `region`  (
  `id` int(0) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

建实体:

package com.jiangxb.transactional;

import lombok.Builder;
import lombok.Data;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

/**
 * 地区实体
 *
 * @author: jiangxiangbo
 * @date: 2021/6/16
 */
@Entity
@Table(name = "region")
@Data
@Builder
public class Region {
   

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    
    @Column(name = "name")
    private String name;
    
}

repository:

package com.jiangxb.transactional;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

/**
 * region repository
 *
 * @author: jiangxiangbo
 * @date: 2021/6/16
 */
@Repository
public interface RegionRepository extends JpaRepository<Region, Long> {
   
}

service:

package com.jiangxb.transactional;

import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * 地区service
 *
 * @author: jiangxiangbo
 * @date: 2021/6/16
 */
@Service
public class RegionService {
   
    
    @Autowired
    private RegionRepository regionRepository;
    
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void insertRegion() {
   
        regionRepository.save(Region.builder().name("A").build());
        
        // 调用同个类中的事务方法需要使用代理对象调用,否则事务无效
        RegionService regionService = (RegionService)AopContext.currentProxy();
        regionService.insertRegionB();
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void insertRegionB() {
   
        regionRepository.save(Region.builder().name("B").build());
//        throw new RuntimeException();
    }
}

controller:


                
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值