我们在前面已经分别介绍了如何在Spring Boot中使用JPA(初识在Spring Boot中使用JPA)以及如何在Spring Boot中输出REST资源(在Spring Boot中输出REST资源)。那么关于数据库访问还有一个核心操作那就是事务的处理了,前面两篇博客小伙伴们已经见识到Spring Boot带给我们的巨大便利了,其实不用猜,我们也知道Spring Boot在数据库事务处理问题上也给我们带来惊喜,OK,废话不多说,就来看看如何在Spring Boot中使用事务吧。

可能还是会有一些小伙伴对Spring Boot并不是特别熟悉,不熟悉的小伙伴请移步这里从SpringMVC到Spring Boot,老司机请忽略。

OK,那我们开始今天愉快的coding旅程吧!

创建Project并添加数据库依赖

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



OK,工程创建成功之后接下来我们来添加数据库驱动,和前文一样,我这里还是以MySql数据库为例,在pom.xml文件中添加如下依赖:

<dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.40</version>
        </dependency>

配置application.properties

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

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/rest
spring.datasource.username=root
spring.datasource.password=sang

spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jackson.serialization.indent_output=true

创建实体类

实体类还是一个Person,如下:

@Entity
public class Person {
    @Id
    @GeneratedValue
    private Long id;
    private String name;
    private String address;
    private Integer age;

    public Person() {
    }

    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 getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Person(Long id, String name, String address, Integer age) {
        this.id = id;
        this.name = name;
        this.address = address;
        this.age = age;
    }
}

创建实体类的Repository

public interface PersonRepository extends JpaRepository<Person,Long> {
}

这里因为我们的目的是测试事务,所以Repository中暂时先不写任何东西。

创建业务服务Service

创建Service接口

public interface DemoService {
    public Person savePersonWithRollBack(Person person);

    public Person savePersonWithoutRollBack(Person person);
}

创建Service实现类

@Service
public class DemoServiceImpl implements DemoService {
    @Autowired
    PersonRepository personRepository;

    @Transactional(rollbackFor = {IllegalArgumentException.class})
    @Override
    public Person savePersonWithRollBack(Person person) {
        Person p = personRepository.save(person);
        if (person.getName().equals("sang")) {
            throw new IllegalArgumentException("sang 已存在,数据将回滚");
        }
        return p;
    }

    @Transactional(noRollbackFor = {IllegalArgumentException.class})
    @Override
    public Person savePersonWithoutRollBack(Person person) {
        Person p = personRepository.save(person);
        if (person.getName().equals("sang")) {
            throw new IllegalArgumentException("sang已存在,但数据不会回滚");
        }
        return p;
    }
}

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

创建控制器

@RestController
public class MyController {
    @Autowired
    private DemoService demoService;

    @RequestMapping("/norollback")
    public Person noRollback(Person person) {
        return demoService.savePersonWithoutRollBack(person);
    }

    @RequestMapping("/rollback")
    public Person rollback(Person person) {
        return demoService.savePersonWithRollBack(person);
    }
}

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

测试

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



看看控制台抛出的异常:



这个时候再去查看数据库,发现数据表中并没有插入数据。

再在地址栏输入http://localhost:8080/norollback?name=sang&age=100,测试结果如下:

浏览器依然报错:



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

OK,以上就是数据库事务在Spring Boot中的简单使用。

本文案例下载:

本文案例GitHub地址https://github.com/lenve/JavaEETest/tree/master/Test24-Transaction

更多Spring Boot资料请移步这里从SpringMVC到Spring Boot

以上。

参考资料:

《JavaEE开发的颠覆者 Spring Boot实战》第八章

在Spring Boot中使用数据库事务的更多相关文章

  1. 【Spring Boot&&Spring Cloud系列】Spring Boot中使用数据库之MySql

    对于传统关系型数据库来说,Spring Boot使用JPA(Java Persistence API)资源库提供持久化的标准规范,即将Java的普通对象通过对象关系映射(ORM)持久化到数据库中. 项 ...

  2. spring boot中的声明式事务管理及编程式事务管理

    这几天在做一个功能,具体的情况是这样的: 项目中原有的几个功能模块中有数据上报的功能,现在需要在这几个功能模块的上报之后生成一条消息记录,然后入库,在写个接口供前台来拉取消息记录. 看到这个需求,首先 ...

  3. Spring Boot中的事务管理

    原文  http://blog.didispace.com/springboottransactional/ 什么是事务? 我们在开发企业应用时,对于业务人员的一个操作实际是对数据读写的多步操作的结合 ...

  4. Spring Boot中使用MongoDB数据库

    前段时间分享了关于Spring Boot中使用Redis的文章,除了Redis之后,我们在互联网产品中还经常会用到另外一款著名的NoSQL数据库MongoDB. 下面就来简单介绍一下MongoDB,并 ...

  5. Spring Boot中的事务是如何实现的

    本文首发于微信公众号[猿灯塔],转载引用请说明出处 今天呢!灯塔君跟大家讲: Spring Boot中的事务是如何实现的 1. 概述 一直在用SpringBoot中的@Transactional来做事 ...

  6. Spring Boot中使用PostgreSQL数据库

    在如今的关系型数据库中,有两个开源产品是你必须知道的.其中一个是MySQL,相信关注我的小伙伴们一定都不陌生,因为之前的Spring Boot关于关系型数据库的所有例子都是对MySQL来介绍的.而今天 ...

  7. 【Spring Boot&&Spring Cloud系列】Spring Boot中使用NoSql数据库Redis

    github地址:https://github.com/AndyFlower/Spring-Boot-Learn/tree/master/spring-boot-nosql-redis 一.加入依赖到 ...

  8. 使用spring boot中的JPA操作数据库

    前言 Spring boot中的JPA 使用的同学都会感觉到他的强大,简直就是神器一般,通俗的说,根本不需要你写sql,这就帮你节省了很多时间,那么下面我们来一起来体验下这款神器吧. 一.在pom中添 ...

  9. Spring Boot中使用时序数据库InfluxDB

    除了最常用的关系数据库和缓存之外,之前我们已经介绍了在Spring Boot中如何配置和使用MongoDB.LDAP这些存储的案例.接下来,我们继续介绍另一种特殊的数据库:时序数据库InfluxDB在 ...

随机推荐

  1. Menu-右键弹出菜单

    #右键弹出菜单 from tkinter import * root=Tk() def callback(): print('我被调用了') menubar =Menu(root) menubar.a ...

  2. jacascript 滚动 scroll 与回到顶部

    前言:这是笔者学习之后自己的理解与整理.如果有错误或者疑问的地方,请大家指正,我会持续更新! 滚动 scroll scrollHeight 表示元素的总高度,包括由于溢出而无法展示在网页的不可见部分: ...

  3. myeclipse自动添加注释

    开发需要,新建类的时候,需要加自己的名字,每次都要自己写,嫌麻烦,修改一下myeclipse配置文件即可 打开window---preferences 选中 new Java files 点击edit ...

  4. Java四种线程池的学习与总结

    在Java开发中,有时遇到多线程的开发时,直接使用Thread操作,对程序的性能和维护上都是一个问题,使用Java提供的线程池来操作可以很好的解决问题. 一.new Thread的弊端 执行一个异步任 ...

  5. C++ 前期准备

    在线编译网站: http://www.dooccn.com/cpp/ 刷题: https://leetcode.com/ https://leetcode-cn.com/

  6. clique

    [题目描述]数轴上有 n 个点,第 i 个点的坐标为 xi,权值为 wi.两个点 i,j 之间存在一条边当且仅当 abs(xi-xj)>=wi+wj.你需要求出这张图的最大团的点数.(团就是两两 ...

  7. [Apio2009]Atm

    题目描述 输入 第一行包含两个整数N.M.N表示路口的个数,M表示道路条数.接下来M行,每行两个整数,这两个整数都在1到N之间,第i+1行的两个整数表示第i条道路的起点和终点的路口编号.接下来N行,每 ...

  8. 51 nod 1515 明辨是非(并查集合并)

    1515 明辨是非题目来源: 原创基准时间限制:1 秒 空间限制:131072 KB 分值: 160 难度:6级算法题 给n组操作,每组操作形式为x y p. 当p为1时,如果第x变量和第y个变量可以 ...

  9. 【BZOJ2243】【SDOI2011】染色

    题意见试题传送门 解题思路:显然是题树剖题. 考虑用线段树维护区间端点颜色与颜色数,这样就可以方便的合并,注意查询的时候对端点的特殊处理即可. 时间效率最高为\( O (m \log^{2} n) \ ...

  10. hdu 2865 Polya计数+(矩阵 or 找规律 求C)

    Birthday Toy Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...