前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring Boot中的事务管理:保证数据的一致性和可靠性

Spring Boot中的事务管理:保证数据的一致性和可靠性

原创
作者头像
bug菌
修改2023-09-27 17:17:17
7180
修改2023-09-27 17:17:17
举报

🏆本文收录于《Spring Boot从入门到精通》,专门攻坚指数提升,2023 年国内最系统+最强(更新中)。

代码语言:javascript
复制
环境说明:Windows10 + Idea2021.3.2 + Jdk1.8 + SpringBoot 2.3.1.RELEASE

前言

在Web应用程序中处理多个数据库操作时,可能会遇到数据不一致的问题。为了解决这个问题,Java中有一个叫做事务的机制。Spring Boot为我们提供了一种方便和简单的方式来实现事务的管理。

在本文中,我们将学习如何在Spring Boot应用程序中使用事务,以确保数据一致性。

摘要

在本文中,我们将学习以下内容:

  1. 什么是事务?
  2. Spring Boot中的事务管理
  3. 事务管理的四种传播行为
  4. 事务管理的三种隔离级别
  5. 如何在Spring Boot应用程序中使用事务
  6. 如何在Spring Boot应用程序中测试事务

正文

什么是事务?

事务是指一系列操作,这些操作要么全部成功,要么全部失败。事务的目的是确保数据一致性。如果在事务中执行一个操作失败,则该事务必须被回滚。这意味着,所有在该事务中执行的操作都必须撤销。

Spring Boot中的事务管理

Spring Boot为我们提供了一个方便的机制来管理事务。在Spring Boot中,我们可以使用注解来声明一个方法是一个事务。

事务管理的四种传播行为

在Spring Boot中,我们可以使用传播行为定义事务处理方法的行为。Spring Boot提供了以下四种传播行为:

  1. REQUIRED:如果一个方法在另一个方法中被调用,那么它将在当前事务中运行。如果当前没有活动的事务,则它将创建一个新事务。
  2. REQUIRES_NEW:如果一个方法在另一个方法中被调用,那么它将在新事务中运行。如果当前有一个活动的事务,则它将被挂起。
  3. SUPPORTS:如果一个方法在另一个方法中被调用,那么它将在当前事务中运行。如果当前没有活动的事务,则它将以非事务方式运行。
  4. NOT_SUPPORTED:如果一个方法在另一个方法中被调用,那么它将以非事务方式运行。如果当前有一个活动的事务,则它将被挂起。

事务管理的三种隔离级别

在Spring Boot中,我们可以使用隔离级别定义事务的隔离级别。Spring Boot提供了以下三种隔离级别:

  1. DEFAULT:使用默认的隔离级别。
  2. READ_COMMITTED:该隔离级别允许读取已提交的数据。其他事务已经提交的数据将被读取。
  3. READ_UNCOMMITTED:该隔离级别允许读取未提交的数据。其他事务未提交的数据也可以被读取。

如何在Spring Boot应用程序中使用事务

在Spring Boot应用程序中使用事务非常简单。我们只需要在要执行事务的方法上加上一个@Transactional注解即可。例如,以下是一个使用事务的示例:

代码语言:java
复制
@Transactional
public void transferMoney(Account from, Account to, BigDecimal amount) {
    if (from.getBalance().compareTo(amount) < 0) {
        throw new InsufficientFundsException("Insufficient funds in account " + from.getId());
    }
    from.setBalance(from.getBalance().subtract(amount));
    to.setBalance(to.getBalance().add(amount));
    accountRepository.save(from);
    accountRepository.save(to);
}

在上面的示例中,我们使用@Transactional注解将transferMoney方法标记为一个事务方法。如果在方法执行期间发生异常,则事务将回滚。否则,事务将提交。

如何在Spring Boot应用程序中测试事务

在Spring Boot应用程序中测试事务非常容易。我们只需要在测试类上添加以下注解:

代码语言:java
复制
@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional
public class MyServiceTest {

    @Autowired
    private MyService myService;

    // ...

}

在上面的示例中,我们使用了@Transactional注解来标记测试类,这将确保测试方法在执行后自动回滚事务。这样,我们就可以在测试过程中执行事务并确保数据一致性。

代码演示

以下是使用Spring Boot的一个简单示例,其中演示了如何使用事务。

Account.java

代码语言:java
复制
@Entity
public class Account {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String name;

    private BigDecimal balance;

    // getters and setters

}

AccountRepository.java

代码语言:java
复制
@Repository
public interface AccountRepository extends CrudRepository<Account, Long> {

}

AccountService.java

代码语言:java
复制
@Service
public class AccountService {

    private final AccountRepository accountRepository;

    public AccountService(AccountRepository accountRepository) {
        this.accountRepository = accountRepository;
    }

    @Transactional
    public void transferMoney(Account from, Account to, BigDecimal amount) {
        if (from.getBalance().compareTo(amount) < 0) {
            throw new InsufficientFundsException("Insufficient funds in account " + from.getId());
        }
        from.setBalance(from.getBalance().subtract(amount));
        to.setBalance(to.getBalance().add(amount));
        accountRepository.save(from);
        accountRepository.save(to);
    }

}

AccountController.java

代码语言:java
复制
@RestController
@RequestMapping("/accounts")
public class AccountController {

    private final AccountService accountService;

    public AccountController(AccountService accountService) {
        this.accountService = accountService;
    }

    @PostMapping("/transfer")
    public void transferMoney(
            @RequestParam Long fromId,
            @RequestParam Long toId,
            @RequestParam BigDecimal amount) {

        Account from = accountService.getAccountById(fromId);
        Account to = accountService.getAccountById(toId);

        accountService.transferMoney(from, to, amount);

    }

}

AccountControllerTest.java

代码语言:java
复制
@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional
public class AccountControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Autowired
    private AccountService accountService;

    @Test
    public void testTransferMoney() throws Exception {
        Account from = new Account();
        from.setName("from");
        from.setBalance(new BigDecimal("100.00"));
        accountService.saveAccount(from);

        Account to = new Account();
        to.setName("to");
        to.setBalance(new BigDecimal("100.00"));
        accountService.saveAccount(to);

        mockMvc.perform(post("/accounts/transfer")
                .param("fromId", from.getId().toString())
                .param("toId", to.getId().toString())
                .param("amount", "50.00"))
                .andExpect(status().isOk());

        from = accountService.getAccountById(from.getId());
        to = accountService.getAccountById(to.getId());

        assertThat(from.getBalance()).isEqualTo(new BigDecimal("50.00"));
        assertThat(to.getBalance()).isEqualTo(new BigDecimal("150.00"));
    }

}

附录源码

  如上涉及所有源码均已上传同步在「GitHub」,提供给同学们一对一参考学习,辅助你更迅速的掌握。

小结

在本文中,我们学习了在Spring Boot应用程序中使用事务的方法。我们了解了事务的概念,以及Spring Boot提供的事务管理机制。我们学习了事务的四种传播行为和三种隔离级别,并且了解了如何在Spring Boot应用程序中使用事务。最后,我们还介绍了如何在Spring Boot应用程序中测试事务。

希望这篇文章对你有所帮助!

总结

事务是确保数据一致性的重要机制,而Spring Boot提供了一种简单方便的事务管理机制。在开发应用程序时,我们应该充分利用Spring Boot的事务管理机制来确保数据一致性。在编写测试用例时,我们也应该使用@Transactional注解和其他相关的注解来测试我们的事务是否正常工作。

☀️建议/推荐你


无论你是计算机专业的学生,还是对编程有兴趣的小伙伴,都建议直接毫无顾忌的学习此专栏「滚雪球学Spring Boot」,从入门到精通,凡是学习此专栏的同学,均能获取到所需的知识和技能,全网最快速入门SpringBoot,就像滚雪球一样,越滚越大,指数级提升。

📣关于我

我是bug菌,CSDN | 掘金 | InfoQ | 51CTO 等社区博客专家,历届博客之星Top30,掘金年度人气作者Top40,51CTO年度博主Top12,华为云 | 阿里云| 腾讯云等社区优质创作者,全网粉丝合计15w+

我正在参与2023腾讯技术创作特训营第二期有奖征文,瓜分万元奖池和键盘手表

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 摘要
  • 正文
    • 什么是事务?
      • Spring Boot中的事务管理
        • 事务管理的四种传播行为
          • 事务管理的三种隔离级别
            • 如何在Spring Boot应用程序中使用事务
              • 如何在Spring Boot应用程序中测试事务
              • 代码演示
                • Account.java
                  • AccountRepository.java
                    • AccountService.java
                      • AccountController.java
                        • AccountControllerTest.java
                        • 附录源码
                        • 小结
                        • 总结
                        • ☀️建议/推荐你
                        • 📣关于我
                        领券
                        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档