【Spring Cloud Alibaba 温故而知新】(十一)本地事务@Trnsactional 与 Seata分布式事务解决方案

目录

14.1.1 Spring声明式事务 @Transactional 注解解读

14.1.1.1 @Trnsactional 注解解读

  • @Transactional 是 Spring 事务管理提供的注解,在一个方法中加上了这个注解,那么这个方法就将是有事务的,方法内的操作要么一起提交、要么一起回滚

【Spring Cloud Alibaba 温故而知新】(十一)本地事务@Trnsactional 与 Seata分布式事务解决方案_第1张图片

14.1.1.2 @Transactional 注解事务传播行为

  • 它是用来表示当一个事务传播行为修饰的方法被另一个方法调用时,事务如何进行传播
    • methodB 是事务修饰符的方法
    • methodA 调用了 methodB,那么事务应该如何传播?
public class ServiceA {
   
	public void methodA() {
   
		...
		serviceB.methodB();
		...
	}
}
...

public class ServiceB@Transactional (propagation = ...)
	public void methodB(){
   
		...
	}

14.1.1.3 默认传播行为 Propagation.REQUIRED (90%都是使用默认)

  • 支持当前事务;如果当前没有事务,则新建一个事务

【Spring Cloud Alibaba 温故而知新】(十一)本地事务@Trnsactional 与 Seata分布式事务解决方案_第2张图片

14.1.1.4 传播行为 Propagation.NEW

  • 新建事务; 如果当前存在事务,则把当前事务挂起

【Spring Cloud Alibaba 温故而知新】(十一)本地事务@Trnsactional 与 Seata分布式事务解决方案_第3张图片

14.1.1.5 传播行为 Propagation.SUPPORTS

  • 支持当前事务;否则将已非事务方式执行

【Spring Cloud Alibaba 温故而知新】(十一)本地事务@Trnsactional 与 Seata分布式事务解决方案_第4张图片

14.1.1.6 传播行为 Propagation.MANDATORY

  • 支持当前事务; 否则将抛出 IllegalTransactionStateException 异常

【Spring Cloud Alibaba 温故而知新】(十一)本地事务@Trnsactional 与 Seata分布式事务解决方案_第5张图片

14.1.1.7 传播行为 Propagation.SUPPORTED

  • 不支持当前事务,而是始终以非事务的方式执行 (极少情况使用)

【Spring Cloud Alibaba 温故而知新】(十一)本地事务@Trnsactional 与 Seata分布式事务解决方案_第6张图片

14.1.1.8 传播行为 Propagation.NEVER

  • 以非事务方式执行; 如果当前存在事务,则抛出 IllegalTransactionStateException 异常

【Spring Cloud Alibaba 温故而知新】(十一)本地事务@Trnsactional 与 Seata分布式事务解决方案_第7张图片

14.1.1.9 传播行为 Propagation.NESTED

  • 如果当前存在事务,则对于该传播行为修饰的方法会依然使用当前事务

【Spring Cloud Alibaba 温故而知新】(十一)本地事务@Trnsactional 与 Seata分布式事务解决方案_第8张图片

14.2.1 Spring事务 @Transactioal 注解的应用

14.2.1.1 @Transactioal 注解最常见的应用

  • 可以标注在类、方法和接口(不要这样用)上;且方法上的注解会覆盖类上的注解
  • 标注在方法上,标识开启事务功能,正常则提交、异常则回滚
  • 自行执行 rollbackFor 属性,让 Checked Exception 也能够实现回滚
  • 让 TestCase 也能够实现回滚

14.2.1.2 Dao层 单元测试

edcode-study-scacommerce 工程

Maven依赖


<dependency>
    <groupId>mysqlgroupId>
    <artifactId>mysql-connector-javaartifactId>
    <version>8.0.19version>
dependency>

<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-data-jpaartifactId>
dependency>

application-dev.yml

spring:
	# ... 省略
  jpa:
    show-sql: true
    hibernate:
      ddl-auto: none # create-drop 第一次建表使用,之后用 none
    properties:
      hibernate.show_sql: true
      hibernate.format_sql: true
    open-in-view: false
  datasource:
    # 数据源
    url: jdbc:mysql://192.168.3.250:3306/edcode_study_springboot?autoReconnect=true&useUnicode=true&characterEncoding=utf8&useSSL=false
    username: root
    password: 123456
    type: com.zaxxer.hikari.HikariDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    # 连接池
    hikari:
      maximum-pool-size: 8
      minimum-idle: 4
      idle-timeout: 30000
      connection-timeout: 30000
      max-lifetime: 45000
      auto-commit: true
      pool-name: EdCodeStudyEcommerce

用户表实体类定义

@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "springboot_user")
public class JpaSpringBootUser {
   

	/** 主键 id */
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "id", nullable = false)
	private Integer id;

	/** 用户名 */
	@Basic
	@Column(name = "user_name", nullable = false)
	private String username;
}

JpaSpringBootUser Dao 接口定义

public interface SpringBootUserRepository extends JpaRepository<JpaSpringBootUser, Integer> {
   
}

Spring 事务管理测试 - 回滚测试

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class TransactionTest {
   

	@Autowired
	private SpringBootUserRepository springBootUserRepository;
	/**
	 * 测试保存数据表记录的事务问题
	 */
	@Transactional
	@Test
	public void testCreateSpringBootUser() {
   
		JpaSpringBootUser springBootUser =

你可能感兴趣的:(#,SpringCloud,spring,cloud,分布式,spring)