Spring中@Transactional注解事务传播行为propagation参数说明

说明

在SpringBoot项目中,我们通常使用@Transactional 去进行事务控制,而@Transactional 注解中,有个比较关键的属性就是propagation。在一个多事务的环境中,一个事务方法调用另一个事务方法时,就会涉及到事务的传播行为,该属性用来控制一段代码经过多个@Transactional注解生效(同一个类的不同方法调用@Transactional是不会生效的)的方法的事务传播机制。

对应源码:

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
	/**
	 * The transaction propagation type.
	 * 

Defaults to {@link Propagation#REQUIRED}. * @see org.springframework.transaction.interceptor.TransactionAttribute#getPropagationBehavior() */ Propagation propagation() default Propagation.REQUIRED; }

由源码可知,他是用来指定@Transactional事务传播类型,在不指定的情况下,默认值为Propagation.REQUIRED

而查看Propagation可知,一共有以下7个属性。

/**
 * Enumeration that represents transaction propagation behaviors for use
 * with the {@link Transactional} annotation, corresponding to the
 * {@link TransactionDefinition} interface.
 */
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);
}

每个属性的作用

1.REQUIRED:

默认的传播行为,如果当前存在事务,则加入到当前事务中,如果没有事务,则创建一个新的事务。

这是最常用的选项,适用于大多数业务情况。

2.REQUIRES_NEW

每次都会创建一个新的事务,如果当前存在事务,则将其挂起。这样,每个方法都在自己的事务中运行,互相独立。

使用场景:多个用户同时请求分配某些共享资源,如飞机座位、酒店房间等。你可能希望每个用户的分配操作都在独立的事务中进行,以避免资源冲突问题。使用 REQUIRES_NEW 隔离级别可以确保每个用户的资源分配操作都是独立的,不受其他用户的操作干扰。

3.SUPPORTS

如果当前存在事务,则加入到当前事务中,如果没有事务,则以非事务方式执行。这个选项适用于不需要强制要求事务的方法,可以根据上下文自由选择是否使用事务。

4.NOT_SUPPORTED

以非事务方式执行方法,如果当前存在事务,则将其挂起。适用于不需要事务支持的方法,例如只进行读取操作的方法。

使用场景:有时候我们需要执行一些不需要事务支持的操作,例如在调用远程接口时立刻插入一条日志记录,而不会因为后面的异常,导致事务回滚,调用日志没有留下;或者是插入防重表时,不开启使用直接插入,保证多个事务同时插入同一主键的数据时,能够快速失败,快速抛错,防止无用处理。

5.MANDATORY

要求当前存在事务,否则抛出异常。适用于必须在事务中运行的方法,如果没有事务,则抛出异常。

使用场景:较为重要的,必须开启事务的,较为底层代码,防治被不开启事务调用。

6.NEVER:

要求当前没有事务,否则抛出异常。适用于必须在非事务中运行的方法,如果存在事务,则抛出异常。

使用场景:方法内的数据库操作不希望参与事务,例如插入一条数据时,希望被其他服务或者线程立刻读取到。

7.NESTED

如果当前存在事务,则在当前事务的嵌套事务中执行。如果没有事务,则创建一个新的事务。这个选项适用于需要在事务内部进行嵌套事务的方法。

你可能感兴趣的:(Spring,spring,java,数据库)