Spring声明式事务@Transactional

spring中事务分为声明式事务和编程式事务,本文主要介绍声明式事务

一、声明式事务@Transactional参数

在这里插入图片描述

二、事务传播机制

  • REQUIRED:Spring默认的事务传播机制。支持当前事务;如果不存在事务,则创建一个新的事务。
  • REQUIRES_NEW:创建一个新事务,如果当前存在事务,则暂停当前事务。
  • MANDATORY(强制的):仅支持当前事务;如果当前事务不存在,则抛出异常。
  • NESTED(嵌套):如果存在当前事务,则在该事务中嵌套执行。同时将在这段逻辑事务开始处标记一个保存点,当这个逻辑事务抛出异常回滚时,那么事务将跳转到保存点,从而不影响嵌套事务的外部。当前事务不存在时,同REQUIRED。
  • NEVER:非事务执行,如果存在事务,则抛出异常。
  • SUPPORTS:支持当前事务,如果不存在则以非事务方式执行。
  • NOT_SUPPORTED:以非事务方式执行,如果当前事务存在,则挂起当前事务。

三、事务隔离级别

  • Read Uncommitted(读未提交)
  • Read Committed(读已提交)
  • Repeatable Read(可重复读)(默认)
  • Serializable(可串行化)

四、Spring事务未生效场景

1、抛出事务不支持的异常

原理:
Spring事务默认支持RuntimeException异常,抛出的异常为RuntimeException异常及其子类异常事务均可生效,而我们日常常见的异常基本都继承自RuntimeException,所以无需指定异常类型事务也能生效。但若手动抛出Exception异常,而Exception是RuntimeException的父类,会导致事务不生效。
解决方案:

1.指定Spring事务异常捕获类型
@Transactional(rollbackFor = Exception.class)

2.抛出Spring事务支持的异常类型
throw new RuntimeException("手动抛出运行时异常");

2、使用了try catch

原理:
异常被try catch块捕获,导致事务失效

解决方案:

在catch中抛出Spring事务支持的异常。

3、添加事务的方法必须是public,并且不能带有static、final关键字

4、类未被Spring管理

原理:
Spring实现对象的动态代理,首先这个对象要交由Spring管理。

解决方案:

将类交由Spring管理,可添加@Service注解,或使用其他能够注册成Spring Bean的注解或方法。

5、数据表不支持事务

原理:
Spring事务基于数据库事务实现,有些数据表本身不支持事务,如MySql的MyISAM引擎,事务自然不生效。

解决方案:

将数据表改用支持事务的引擎,如MySql的InnoDB引擎。

6、Spring事务传播级别设置为不支持事务

原理:
@Transactional(propagation = Propagation.NOT_SUPPORTED) 不支持事务,若存在事务则挂起
@Transactional(propagation = Propagation.NEVER) 不使用事务,若存在事务则抛异常

解决方案:

使用Spring默认的传播级别(PROPAGATION_REQUIRED),或其他支持事务的传播级别。

7、未开启事务

解决方案:

@EnableTransactionManagement开启事务,Spring boot已自动装配,无需显示使用此注解。

8、多线程调用

@Transactional注解只能对当前线程的事务进行管理,而对于多个线程之间的事务协调和管理,需要使用分布式事务进行控制。可以使用Spring Cloud提供的分布式事务管理器,如Seata、TCC等,来协调多个线程之间的事务,确保事务的一致性。

猜你喜欢

转载自blog.csdn.net/weixin_44183847/article/details/129339495