SpringBoot - 声明式事务管理

感谢作者: http://blog.720ui.com/2017/springboot_02_data_transactional/

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

声明式事务

Spring 支持声明式事务,使用 @Transactional 注解在方法上表明这个方法需要事务支持。此时,Spring 拦截器会在这个方法调用时,开启一个新的事务,当方法运行结束且无异常的情况下,提交这个事务。
Spring 提供一个 @EnableTransactionManagement 注解在配置类上来开启声明式事务的支持。使用了 @EnableTransactionManagement 后,Spring 会自动扫描注解 @Transactional 的方法和类。


Spring Boot默认集成事务

Spring Boot 默认集成事务,所以无须手动开启使用 @EnableTransactionManagement 注解,就可以用 @Transactional注解进行事务管理。


数据库准备

CREATE TABLE `t_author` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户ID',
  `real_name` varchar(32) NOT NULL COMMENT '用户名称',
  `nick_name` varchar(32) NOT NULL COMMENT '用户匿名',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;


添加依赖

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.9</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>


实体对象

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

    private Long id;
    private String realName;
    private String nickName;

    public Author() {
    }

    public Author(String realName, String nickName) {
        this.realName = realName;
        this.nickName = nickName;
    }
    // 省略setter/getter
}

DAO层

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

@Repository
public class AuthorDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    public int add(Author author){
        return jdbcTemplate.update(
                "insert into t_author (real_name, nick_name) values(?, ?)",
                author.getRealName(), author.getNickName()
        );
    }
}


Service层

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

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

@Service
public class AuthorService {

    @Autowired
    private AuthorDao authorDao;

    public int add1(Author author){
        int n = this.authorDao.add(author);
        if(author.getRealName().length() > 5){
            throw new IllegalArgumentException("author real name is too long.");
        }
        return n;
    }

    @Transactional(noRollbackFor = {IllegalArgumentException.class})
    public int add2(Author author){
        int n = this.authorDao.add(author);
        if(author.getRealName().length() > 5){
            throw new IllegalArgumentException("author real name is too long.");
        }
        return n;
    }

    @Transactional(rollbackFor = {IllegalArgumentException.class})
    public int add3(Author author){
        int n = this.authorDao.add(author);
        if(author.getRealName().length() > 5){
            throw new IllegalArgumentException("author real name is too long.");
        }
        return n;
    }
}

测试

@RunWith(SpringRunner.class)
@SpringBootTest
public class Combat01ApplicationTests {

    @Autowired
    private AuthorService authorService;

    @Test
    public void add1() {
        authorService.add1(new Author("Ray", "Ray"));
        authorService.add1(new Author("Ray1111", "Ray1111"));
    }

    @Test
    public void add2() {
        authorService.add2(new Author("Ray", "Ray"));
        authorService.add2(new Author("Ray2222", "Ray2222"));
    }

    @Test
    public void add3() {
        authorService.add3(new Author("Ray", "Ray"));
        authorService.add3(new Author("Ray3333", "Ray3333"));
    }
}


测试add1() : 抛出异常, 新增数据成功


测试add2() : 抛出异常, 新增数据成功(不做事务回滚)


测试add3() : 抛出异常, 新增数据失败(事务回滚)


猜你喜欢

转载自blog.csdn.net/q343509740/article/details/80931442