Spring Boot 揭秘与实战(二) 数据存储篇 - 声明式事务管理

文章目录

  1. 1. 声明式事务
  2. 2. Spring Boot默认集成事务
  3. 3. 实战演练4. 源代码
    1. 3.1. 实体对象
    2. 3.2. DAO 相关
    3. 3.3. Service 相关
    4. 3.4. 测试,测试

本文讲解 Spring Boot 如何使用声明式事务管理。

声明式事务

Spring 支持声明式事务,使用 @Transactional 注解在方法上表明这个方法需要事务支持。此时,Spring 拦截器会在这个方法调用时,开启一个新的事务,当方法运行结束且无异常的情况下,提交这个事务。

Spring 提供一个 @EnableTransactionManagement 注解在配置类上来开启声明式事务的支持。使用了 @EnableTransactionManagement 后,Spring 会自动扫描注解 @Transactional 的方法和类。

Spring Boot默认集成事务

Spring Boot 默认集成事务,所以无须手动开启使用 @EnableTransactionManagement 注解,就可以用 @Transactional注解进行事务管理。我们如果使用到 spring-boot-starter-jdbc 或 spring-boot-starter-data-jpa,Spring Boot 会自动默认分别注入
DataSourceTransactionManager 或 JpaTransactionManager。

实战演练

我们在前文「Spring Boot 揭秘与实战(二) 数据存储篇 - MySQL」的案例上,进行实战演练。

实体对象

我们先创建一个实体对象。为了便于测试,我们对外提供一个构造方法。

  1. public class Author {
  2. private Long id;
  3. private String realName;
  4. private String nickName;
  5.  
  6. public Author() {}
  7. public Author(String realName, String nickName) {
  8. this.realName = realName;
  9. this.nickName = nickName;
  10. }
  11. // SET和GET方法
  12. }

DAO 相关

这里,为了测试事务,我们只提供一个方法新增方法。

  1. @Repository("transactional.authorDao")
  2. public class AuthorDao {
  3.  
  4. @Autowired
  5. private JdbcTemplate jdbcTemplate;
  6.  
  7. public int add(Author author) {
  8. return jdbcTemplate.update("insert into t_author(real_name, nick_name) values(?, ?)",
  9. author.getRealName(), author.getNickName());
  10. }
  11.  
  12. }

Service 相关

我们提供三个方法。通过定义 Author 的 realName 字段长度必须小于等于 5,如果字段长度超过规定长度就会触发参数异常。

值得注意的是,noRollbackFor 修饰表明不做事务回滚,rollbackFor 修饰的表明需要事务回滚。

  1. @Service("transactional.authorService")
  2. public class AuthorService {
  3.  
  4. @Autowired
  5. private AuthorDao authorDao;
  6.  
  7. public int add1(Author author) {
  8. int n = this.authorDao.add(author);
  9. if(author.getRealName().length() > 5){
  10. throw new IllegalArgumentException("author real name is too long.");
  11. }
  12. return n;
  13. }
  14.  
  15. @Transactional(noRollbackFor={IllegalArgumentException.class})
  16. public int add2(Author author) {
  17. int n = this.authorDao.add(author);
  18. if(author.getRealName().length() > 5){
  19. throw new IllegalArgumentException("author real name is too long.");
  20. }
  21. return n;
  22. }
  23.  
  24. @Transactional(rollbackFor={IllegalArgumentException.class})
  25. public int add3(Author author) {
  26. int n = this.authorDao.add(author);
  27. if(author.getRealName().length() > 5){
  28. throw new IllegalArgumentException("author real name is too long.");
  29. }
  30. return n;
  31. }
  32. }

测试,测试

  1. @RunWith(SpringJUnit4ClassRunner.class)
  2. @SpringApplicationConfiguration(WebMain.class)
  3. public class TransactionalTest {
  4.  
  5. @Autowired
  6. protected AuthorService authorService;
  7.  
  8. //@Test
  9. public void add1() throws Exception {
  10. authorService.add1(new Author("梁桂钊", "梁桂钊"));
  11. authorService.add1(new Author("LiangGzone", "LiangGzone"));
  12. }
  13.  
  14. //@Test
  15. public void add2() throws Exception {
  16. authorService.add2(new Author("梁桂钊", "梁桂钊"));
  17. authorService.add2(new Author("LiangGzone", "LiangGzone"));
  18. }
  19.  
  20. @Test
  21. public void add3() throws Exception {
  22. authorService.add3(new Author("梁桂钊", "梁桂钊"));
  23. authorService.add3(new Author("LiangGzone", "LiangGzone"));
  24. }
  25. }

我们分别对上面的三个方法进行测试,只有最后一个方法进行了事务回滚。

源代码

相关示例完整代码: springboot-action

(完)

 

微信公众号
posted @   long77  阅读(825)  评论(0编辑  收藏  举报
编辑推荐:
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
阅读排行:
· 百万级群聊的设计实践
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
点击右上角即可分享
微信分享提示