上述的这几种示例是比较常见使用的,基本可以满足日常我们对事物的使用,spring里面还有一种事物的控制方法,就是设置断点进行回滚 。但是这种方法个人还没实际验证过,可靠性待确认 。
使用方法如下:
Object savePoint =null; try{ //设置回滚点 savePoint = TransactionAspectSupport.currentTransactionStatus().createSavepoint(); }catch(Exception e){ //出现异常回滚到savePoint 。TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savePoint); }上面的使用示例介绍完毕之后,我们再来介绍一下几个主要的类 。
首先还是实体类:
实体类
又是万能的用户表
public class User {private Long id;private String name;private Integer age;//getter 和 setter 略}Controller 控制层
然后便是控制层,控制层这块的我做了下最后的查询,用于校验事物是否成功生效!
控制层代码如下:
@RestController @RequestMapping(value = https://www.isolves.com/it/cxkf/yy/JAVA/2019-08-30/"/api/user") public class UserRestController {@Autowired private UserService userService;@Autowired private UserDao userDao;@PostMapping("/test1") public boolean test1(@RequestBody User user) { System.out.println("请求参数:" + user); try { userService.test1(user); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("最后查询的数据:" + userDao.findById(user.getId())); return true; }@PostMapping("/test2") public boolean test2(@RequestBody User user) {System.out.println("请求参数:" + user); userService.test2(user); System.out.println("最后查询的数据:" + userDao.findById(user.getId())); return true; }@PostMapping("/test3") public boolean test3(@RequestBody User user) {System.out.println("请求参数:" + user); userService.test3(user); System.out.println("最后查询的数据:" + userDao.findById(user.getId())); return true; }@PostMapping("/test4") public boolean test4(@RequestBody User user) {System.out.println("请求参数:" + user); userService.test4(user); System.out.println("最后查询的数据:" + userDao.findById(user.getId())); return true; } }App 入口
和普通的SpringBoot项目基本一样,只不过需要加上 @EnableTransactionManagement 注解!
代码如下:
@EnableTransactionManagement @SpringBootApplication public class TransactionalApp {public static void main( String[] args ) { SpringApplication.run(TransactionalApp.class, args); System.out.println("Transactional 程序正在运行...");} }功能测试
我们在启动程序之后,来进行上述的几个示例测试,这里的测试示例分别对应上述的使用示例,有的示例需要测试两边以上才能验证事物是否能够生效!这里我们使用Postman进行测试!
测试示例一
两次测试,第一次不使用@Transactional注解,第二次使用!
第一次测试:
注释掉@Transactional注解!
使用进行POST请求
http://localhost:8182/api/user/test1Body参数为:
{"id":1,"name":"xuwujing","age":18}控制台打印的数据:
请求参数:User [id=1, name=xuwujing, age=18] 查询的数据1:null 查询的数据2:User [id=1, name=xuwujing, age=18] Duplicate entry '1' for key 'PRIMARY' 最后查询的数据:User [id=1, name=xuwujing, age=18]第二次测试:
解除@Transactional注解注释!
使用进行POST请求
http://localhost:8182/api/user/test1Body参数为:
{"id":1,"name":"xuwujing","age":18}控制台打印的数据:
请求参数:User [id=1, name=xuwujing, age=18] 查询的数据1:null 查询的数据2:User [id=1, name=xuwujing, age=18] Duplicate entry '1' for key 'PRIMARY' 最后查询的数据:null注: 在第二次测试的之前是把第一次测试写入数据库的id为1的数据个删除了!
第一次测试中由于没有添加@Transactional注解,因此发生了异常数据还是写入了,但是第二次测试中添加了@Transactional注解,发现即使数据已经写入了,但是出现了异常之后,数据最终被回滚了,没有写入!
从上述的测试用例中可以看到测试用例一种的事物已经生效了!
测试示例二
由于使用示例二中的代码几乎和使用示例一种的一样,不同的是异常由我们自己进行控制!
使用进行POST请求
http://localhost:8182/api/user/test2Body参数为:
{"id":1,"name":"xuwujing","age":18}控制台打印的数据:
请求参数:User [id=1, name=xuwujing, age=18] 查询的数据1:null 查询的数据2:User [id=1, name=xuwujing, age=18] 发生异常,进行手动回滚! Duplicate entry '1' for key 'PRIMARY' 最后查询的数据:null
推荐阅读
- SpringBoot 深度调优,让你的项目飞起来
- SpringBoot2.0 整合 JWT 框架,解决Token跨域验证问题
- SPRINGBOOT之自定义全局异常处理
- SpringBoot配置文件敏感信息加密
- 使用SpringBoot+Dubbo搭建微服务笔记
- 怎么判断茶汤的好坏
- 分布式系统常见概念
- java学习中springboot和ssm开发的区别
- 阿里架构师分享技术干货Spring+Redis+SpringBoot+Nginx等实践
- 学围棋的好处
