(五)Spring Boot 事务支持 —— 《一步一步学 Spring Boot 2》读书笔记

本文深入探讨Spring事务管理,包括编程式与声明式事务的区别,Spring如何提供事务抽象层,以及在SpringBoot中的具体应用。文章详细解释了事务的传播行为和隔离级别,通过实例演示了如何使用@Transactional注解进行事务控制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文纯个人读书笔记,书籍《一步一步学 Spring Boot 2》
如果喜欢,可直接购买书籍。如有侵权,请联系删除

一、Spring 事务

Spring 事务主要是用来保证数据的完整性和一致性。Spring 在不同的事务管理 API 之上定义了一个抽象层,而应用程序开发人员不必了解底层的事务管理 API,就可以使用 Spring 的事务管理机制。

Spring 既支持编程式事务管理(也称编码式事务),也支持声明式的事务管理。
编程式事务管理是指将事务管理代码嵌入到业务方法中来控制事务的提交和回滚。在编程式事务中,必须在每个业务操作中包含额外的事务管理代码。
声明式事务管理是指将事务管理代码从业务方法中分离出来,以声明的方式来实现事务管理。大多数情况下声明式事务管理比编程式事务管理更好用。Spring 通过 Spring AOP 框架支持声明式事务管理。

Spring 在不同的事务管理 API 之上定义了一个抽象层 PlatformTransactionManager,并且提供了许多事务管理器的实现:DataSourceTransactionManager、JdoTransactionManager、JpaTransactionManager、以及HibernateTransactionManager等等。开发人员不必了解底层的事务管理 API,就可以使用 Spring 的事务管理机制。

1.声明式事务

Spring 声明式事务目前比较流行的是使用注解方式。我们可以使用 @Transactional 注解在类或者方法上表明该类或者方法需要事务支持。被注解的类或者方法被调用时,Spring开启一个新的事务,当方法正常运行时,Spring 会提交这个事务。

这里需要注意的是,@Transactional 注解来自 org.springframework.transaction.annotation。Spring 提供了@EnableTransactionManagement 注解在配置类上来开启声明式事务的支持。使用 @EnableTransactionManagement 后,Spring 容器会自动扫描注解 @Transactional 的方法和类。

2.Spring 传播行为

当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。事务的传播行为可以在 @Transactional 的属性中指定。Spring定义了7种传播行为,

Spring 传播行为:
在这里插入图片描述
@Transactional 可以通过 propagation 属性定义事务的传播行为,属性值分别为:REQUIRED、SUPPORTS、MANDATORY、REQUIRES_NEW、NOT_SUPPORTED、NEVER 和 NESTED,对应上面的 7 个值。

3.Spring 隔离级别

多个事务并发运行时,经常会操作相同的数据来完成各自的任务,这时候会导致一些问题,

① 脏读(Dirty reads): 脏读发生在一个事务读取了另一个事务改写但尚未提交的数据。如果改写在稍后被回滚了,那么第一个事务获取的数据就是无效的。

② 不可重复读(Nonrepeatable read): 不可重复读发生在一个事务执行相同的查询两次或两次以上,但是每次都得到不同的数据时。这通常是因为另一个并发事务在两次查询期间更新了数据。
③ 幻读(Phantom read): 幻读与不可重复读类似。它发生在一个事务(T1)读取了几行数据,接着另一个并发事务(T2)插入了一些数据时。在随后的查询中,第一个事务(T1)就会发现多了一些原本不存在的记录。

针对这些问题,Spring 提供了五种事务的隔离级别。

Spring 隔离级别:
在这里插入图片描述
@Transactional 可以通过 isolation 属性定义隔离级别,属性值分别为:DEFAULT、READ_UNCOMMITTED、READ_COMMITTED、REPEATABLE_READ 和 SERIALIZABLE,分别对应上面的 5 个值。

二、Spring Boot 中事务的使用

Spring Boot 默认对 JPA、JDBC、Mybatis 开启了事事务,直接使用注解 @Transactional 就可以。如果使用其它的 ORM 框架,就需要自己配置相关的事物管理器。

其他与正常的事务使用没有任何区别,分为类级别事务和方法级别事务。

类级别事务:

@Service
@Transactional
public class UserServiceImpl implements UserService {
	......
}

方法级别事务:

    @Override
    @Transactional
    public User save(User user) {
        // 出现空指针异常
        userRepository.save(user);
        return user;
    }

注解在类上的时候,此类的所有 public 方法都开启事务的。如果类级别和方法级别同时使用了 @Transactional 注解,则方法级别注解覆盖类级别注解。

三、测试

修改 com.xiaoyue.demo.service.impl.UserServiceImpl 的 save 方法,模拟出现异常。

UserServiceImpl.java:

@Service
@Transactional
public class UserServiceImpl implements UserService {

    @Resource
    private UserRepository userRepository;

    @Override
    public User save(User user) {

        userRepository.save(user);
        // 模拟异常
        int i = 10 / 0;
        return user;
    }
    ......
}

在测试类 DemoApplicationTests.java 中添加测试代码并运行。

DemoApplicationTests.java:

    @Test
    public void testTransaction () {
        User user =new User( );
        user.setId ("5");
        user.setName("test");
        user.setPassword ("123456") ;
        userService.save(user);
    }

运行结果会发现数据库没有数据添加。如果在 service 中把 @Transactional 去掉,可以发现,添加成功。说明事务生效。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值