美文网首页springboot
在Spring Boot中使用数据库事务

在Spring Boot中使用数据库事务

作者: rainbowz | 来源:发表于2019-01-23 20:05 被阅读15次

关于数据库访问还有一个核心操作那就是事务的处理了,前面两篇博客小伙伴们已经见识到Spring Boot带给我们的巨大便利了,其实不用猜,我们也知道Spring Boot在数据库事务处理问题上也给我们带来惊喜,OK,废话不多说,就来看看如何在Spring Boot中使用事务吧。
可能还是会有一些小伙伴对Spring Boot并不是特别熟悉,不熟悉的小伙伴请移步这里从SpringMVC到Spring Boot,老司机请忽略。

创建Project并添加数据库依赖

这个没啥好说的,不懂如何创建一个Spring Boot工程的小伙伴请移步这里初识Spring Boot框架。创建的时候选择依赖时选择Web和JPA,如下图:

图片.png
             <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

                <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
           <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
    </dependency>

配置application.properties

配置方式还是和前文一模一样,不懂的小伙伴请移步这里初识在Spring Boot中使用JPA,我这里直接贴代码,含义不再赘述:

spring.datasource.url=jdbc:mysql://127.0.0.1/springboot2?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=true
spring.datasource.username=root
spring.datasource.password=514730
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.show-sql= true

spring.thymeleaf.cache=false

#中文
spring.http.encoding.charset=UTF-8
spring.http.encoding.force=true
spring.http.encoding.enabled=true

SQL

-- auto-generated definition
CREATE TABLE book
(
  id           INT AUTO_INCREMENT
    PRIMARY KEY,
  name         VARCHAR(255) NULL,
  writer       VARCHAR(255) NULL,
  introduction VARCHAR(255) NULL
)
  ENGINE = InnoDB;

图片.png

创建实体类

package com.demo.entity;

import javax.persistence.*;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotEmpty;

@Entity
@Table
public class Book {
    @Id
    @GeneratedValue()
    private  Long id;

    @NotEmpty(message = "姓名不能为空")
    @Column(length=50)
    private  String name;

    @NotEmpty(message = "writer不能为空")
    private  String writer;

    @NotEmpty(message = "introduction不能为空")
    private  String introduction;

    public Book() {
    }

    @Override
    public String toString() {
        return "Book{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", writer='" + writer + '\'' +
                ", introduction='" + introduction + '\'' +
                '}';
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getWriter() {
        return writer;
    }

    public void setWriter(String writer) {
        this.writer = writer;
    }

    public String getIntroduction() {
        return introduction;
    }

    public void setIntroduction(String introduction) {
        this.introduction = introduction;
    }
}

创建实体类的Repository

import org.springframework.data.jpa.repository.JpaRepository;

public interface BookDao  extends JpaRepository<Book,Long>{
}

创建业务服务Service

创建Service接口

package com.demo.service;

import com.demo.entity.Book;

public interface BookService {
    public  void add(Book book);

    public Book savePersonWithRollBack(Book person);

    public Book savePersonWithoutRollBack(Book person);

}

创建Service实现类

@Service
@Transactional
public class BookServiceImpl implements BookService {

    @Resource
    BookDao dao;

    public void add(Book book) {
        dao.save(book);
    }

    @Transactional(rollbackFor = {IllegalArgumentException.class})
    public Book savePersonWithRollBack(Book person) {
        Book book= dao.save(person);
        if (person.getName().equals("sang")){
            throw  new IllegalArgumentException("sang已经存在 数据将回滚");
        }
        return book;
    }


    @Transactional(noRollbackFor = {IllegalArgumentException.class})
    public Book savePersonWithoutRollBack(Book person) {
        Book book= dao.save(person);
        if (person.getName().equals("sang")){
            throw  new IllegalArgumentException("sang已经存在 但数据不会回滚");
        }
        return book;
    }
}

在这里我们使用到了@Transactional注解,该注解中有一个rollbackFor属性,该属性的值为数组,表示当该方法中抛出指定的异常时数据回滚,该注解还有个属性叫noRollbackFor,表示当该方法中抛出指定的异常时数据不回滚,这两个属性我们分别在两个方法中体现。

创建控制器

@RestController
public class BookController2 {

        @Autowired
    BookService service;

    @RequestMapping("/norollback")
    public Book noRollback(Book book) {
        return service.savePersonWithoutRollBack(book);
    }
        @RequestMapping("/rollback")
        public Book rollback(Book book)
        {
            return service.savePersonWithRollBack(book);
        }

}

控制器创建成功之后接下来我们就可以直接在浏览器中访问这两个地址看看效果了。
测试

首先在浏览器中输入
http://localhost:8080/rollback?name=sang&writer=施耐庵&introduction=小说
我们来测试回滚的情况,访问结果如下:

图片.png
看看控制台抛出的异常:
图片.png
这个时候再去查看数据库,发现数据表中并没有插入数据

再在地址栏输入
http://localhost:8080/norollback?name=sang&writer=施耐庵&introduction=小说
测试结果如下,浏览器依然报错:

图片.png
控制台也打印了错误,但是这个时候再去看数据库,数据已成功插入了。如下图:
图片.png
图片.png

参考资料:
https://blog.csdn.net/u012702547/article/details/54098190
《JavaEE开发的颠覆者 Spring Boot实战》第八章

相关文章

网友评论

    本文标题:在Spring Boot中使用数据库事务

    本文链接:https://www.haomeiwen.com/subject/kyvsjqtx.html