Spring Boot 快速上手(四)事务使用
来源:互联网 发布:精神发育迟缓症状知乎 编辑:程序博客网 时间:2024/05/19 02:16
在上一篇中已经讲到了Spring Boot中使用JPA对数据库进行操作,通常在对数据库数据进行维护时会使用到事务,本文接下来将会简单介绍下Spring Boot中事务的使用。
Debug模式启动Spring Boot,访问http://localhost:8088/demo/student/saveStudentWithRoolBack?name=Mike&age=25&nat=USA,开发工具中可看到如下结果:
可以看到,此时数据库已为新数据分配主键值1,但此时新数据尚不可读取。
java.lang.ArithmeticException继承了RuntimeException,故此时新增数据应该已经回滚。
Debug模式启动Spring Boot,访问http://localhost:8088/demo/student/saveStudentWithoutRoolBack?name=Mike&age=25&nat=USA,开发工具中可看到如下结果:
可以看到,此时数据库已为新数据分配主键值2,继续运行,控制台依然会打印异常:java.lang.ArithmeticException: / by zero。
注意:如果真的希望发生数据异常时不回滚,那么noRollbackFor属性必须要指定异常类,并且不要设置rollbackFor属性。
1.数据准备
①pom.xml配置
pom.xml文件中的必要依赖如下:<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency>这里依然是使用MySQL数据库做演示,如果使用其他数据库,更换相关数据库驱动即可。
②application.properties配置
# 访问路径server.context-path=/demo# 端口号server.port=8088## 数据源配置spring.datasource.driverClassName=com.mysql.jdbc.Driverspring.datasource.url=jdbc:mysql://127.0.0.1:3306/demo?characterEncoding=UTF-8spring.datasource.username=rootspring.datasource.password=root## JPA配置spring.jpa.show-sql=truespring.jackson.serialization.indent_output=true
③数据库建表
本文依然使用数据库表:student(学生表),建表sql如下:CREATE TABLE `student` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', `name` varchar(100) DEFAULT NULL COMMENT '姓名', `age` int(4) DEFAULT NULL COMMENT '年龄', `nat` varchar(200) DEFAULT NULL COMMENT '国籍', PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='学生表'
④创建实体类
学生表Student:package net.xxpsw.demo.springboot.student.entity;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;@Entitypublic class Student {@Id@GeneratedValueprivate Long id;private String name;private Integer age;private String nat;public Student() {super();}public Student(String name, Integer age, String nat) {super();this.name = name;this.age = age;this.nat = nat;}public Student(Long id, String name, Integer age, String nat) {super();this.id = id;this.name = name;this.age = age;this.nat = nat;}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 Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public String getNat() {return nat;}public void setNat(String nat) {this.nat = nat;}}主键id字段的注解@GeneratedValue作用在于为实体类创建一个自增的唯一值,查看该注解源码如下:
public @interface GeneratedValue { GenerationType strategy() default AUTO; String generator() default "";}该源码中,generator属性声明了主键生成器的名称,默认为"";strategy属性声明了主键生成策略,默认使用javax.persistence.GenerationType.AUTO,表示主键自增。
⑤数据操作
创建数据访问接口StudentRepository:package net.xxpsw.demo.springboot.student.dao;import org.springframework.data.jpa.repository.JpaRepository;import net.xxpsw.demo.springboot.student.entity.Student;public interface StudentRepository extends JpaRepository<Student, Long> {}创建业务层接口StudentService及实现类StudentServiceImpl:
package net.xxpsw.demo.springboot.student.service;public interface StudentService {}
package net.xxpsw.demo.springboot.student.service.impl;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import net.xxpsw.demo.springboot.student.dao.StudentRepository;import net.xxpsw.demo.springboot.student.service.StudentService;@Servicepublic class StudentServiceImpl implements StudentService {@Autowiredprivate StudentRepository studentRepository;}创建控制类StudentController:
package net.xxpsw.demo.springboot.student;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import net.xxpsw.demo.springboot.student.service.StudentService;@RestController@RequestMapping("student")public class StudentController {@Autowiredprivate StudentService studentService;}
2.数据异常回滚
首先演示的是,保存数据后出现了运行异常,导致数据回滚的情况。①控制类
控制类StudentController添加如下方法:/*** @Description: 新增学生信息(异常回滚)* @param name 姓名* @param age 年龄* @param nat 国籍* @return Student */@RequestMapping("saveStudentWithRoolBack")public Student saveStudentWithRoolBack(String name, Integer age, String nat) {return studentService.saveStudentWithRoolBack(new Student(name, age, nat));}
②业务类
业务层实现类StudentServiceImpl添加如下方法:@Transactional(rollbackFor = { RuntimeException.class })@Overridepublic Student saveStudentWithRoolBack(Student student) {Student s = studentRepository.save(student);// by zeroint err = 1 / 0;return s;}此处的事务声明放在了方法上,注解@Transactional的包路径是org.springframework.transaction.annotation.Transactional,rollbackFor属性用以定义需要回滚的异常类型。
③查看源码
查看@Transactional的源码如下:public @interface Transactional {@AliasFor("transactionManager")String value() default "";@AliasFor("value")String transactionManager() default "";Propagation propagation() default Propagation.REQUIRED;Isolation isolation() default Isolation.DEFAULT;int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;boolean readOnly() default false;Class<? extends Throwable>[] rollbackFor() default {};String[] rollbackForClassName() default {};Class<? extends Throwable>[] noRollbackFor() default {};String[] noRollbackForClassName() default {};}从源码中可知rollbackFor属性值为Throwable及其子类,此处使用了子类RuntimeException,实际使用时可根据使用场景合理选择需要监控的异常。
④开发工具调试
为了方便观察,先在saveStudentWithRoolBack方法内的异常处(int err)加上调试断点。Debug模式启动Spring Boot,访问http://localhost:8088/demo/student/saveStudentWithRoolBack?name=Mike&age=25&nat=USA,开发工具中可看到如下结果:
可以看到,此时数据库已为新数据分配主键值1,但此时新数据尚不可读取。
⑤异常信息
继续运行,控制台将会打印如下异常:java.lang.ArithmeticException继承了RuntimeException,故此时新增数据应该已经回滚。
⑥查看数据库
查看数据库表student,结果如下:id name age nat ------ ------ ------ --------可知新数据并未添加成功,查看该数据库表结构,可以看到,主键的自动增量已从1增加为2:
3.数据异常不回滚
接下来演示的是,数据保存后即使出现了异常,数据依然提交成功的情况。①控制类
控制类StudentController中添加如下方法:/*** @Description: 新增学生信息(异常不回滚)* @param name 姓名* @param age 年龄* @param nat 国籍* @return Student */@RequestMapping("saveStudentWithoutRoolBack")public Student saveStudentWithoutRoolBack(String name, Integer age, String nat) {return studentService.saveStudentWithoutRoolBack(new Student(name, age, nat));}
②业务类
业务实现类StudentServiceImpl中添加如下方法:@Transactional(noRollbackFor = { RuntimeException.class })@Overridepublic Student saveStudentWithoutRoolBack(Student student) {Student s = studentRepository.save(student);// by zeroint err = 1 / 0;return s;}此处声明事务时,使用了另外一个属性noRollbackFor,从源码中可知noRollbackFor属性值也是Throwable及其子类,此处使用了子类RuntimeException,实际使用时可根据使用场景合理选择需要监控的异常。
③开发工具调试
为了方便观察,依然先在saveStudentWithoutRoolBack方法内的异常处(int err)加上调试断点。Debug模式启动Spring Boot,访问http://localhost:8088/demo/student/saveStudentWithoutRoolBack?name=Mike&age=25&nat=USA,开发工具中可看到如下结果:
可以看到,此时数据库已为新数据分配主键值2,继续运行,控制台依然会打印异常:java.lang.ArithmeticException: / by zero。
④查看数据库
查看数据库表student,结果如下:id name age nat ------ ------ ------ -------- 2 Mike 25 USA从查询结果可知新数据已提交保存成功,同时该表的主键自动增量已从2增加为3。
注意:如果真的希望发生数据异常时不回滚,那么noRollbackFor属性必须要指定异常类,并且不要设置rollbackFor属性。
阅读全文
0 0
- Spring Boot 快速上手(四)事务使用
- Spring Boot 快速上手(一)快速搭建
- [转]Spring Boot 揭秘与实战(一) 快速上手
- Spring Boot 快速上手(二)基本配置
- Spring Boot 快速上手(三)数据操作
- Spring Boot 快速上手(五)集成Redis
- Spring Boot 快速上手(六)集成MongoDB
- Spring Boot 快速上手(七)集成ActiveMQ
- Spring Boot 快速上手(八)集成Thymeleaf
- Spring Boot 事务的使用
- Spring Boot 事务的使用
- Spring Boot 事务的使用
- Spring Boot 事务的使用
- Spring Boot 事务的使用
- Spring Boot 事务的使用
- Spring Boot 事务的使用
- Spring Boot 事务的使用
- UnityShader快速上手指南(四)
- eclipse下Ctrl+H搜索并替换全项目字符串
- 域名劫持原理及实现
- php web 请求控制
- Bringing up interface eth0: Error:Connection activation failed:Device not managed by NetworkManager
- Python正则表达式中的re.S
- Spring Boot 快速上手(四)事务使用
- 移植Dnsmasq到Android
- 【Struts】struts自带的拦截器
- 51单片机入门前的基础知识
- Studio使用外部的模拟器的adb命令
- 洛谷10月月赛R1·浴谷八连测R1·提高组 一道中档题 Factorial
- 在ubuntu上面安装openfire
- Spring 5 Recipes, 4th Edition.pdf 英文原版免费下载
- 重装系统win7专业版后office卡顿到无法使用解决办法