SpringBoot事物Transaction实战讲解教程 (4)

代码示例:

@Autowired private DataSourceTransactionManager dataSourceTransactionManager; @Autowired private TransactionDefinition transactionDefinition; public boolean test4(User user) { /* * 手动进行事物控制 */ TransactionStatus transactionStatus=null; boolean isCommit = false; try { transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition); System.out.println("查询的数据1:" + udao.findById(user.getId())); // 进行新增/修改 udao.insert(user); System.out.println("查询的数据2:" + udao.findById(user.getId())); if(user.getAge()<20) { user.setAge(user.getAge()+2); udao.update(user); System.out.println("查询的数据3:" + udao.findById(user.getId())); }else { throw new Exception("模拟一个异常!"); } //手动提交 dataSourceTransactionManager.commit(transactionStatus); isCommit= true; System.out.println("手动提交事物成功!"); throw new Exception("模拟第二个异常!"); } catch (Exception e) { //如果未提交就进行回滚 if(!isCommit){ System.out.println("发生异常,进行手动回滚!"); //手动回滚事物 dataSourceTransactionManager.rollback(transactionStatus); } e.printStackTrace(); } return false; }

上述的这几种示例是比较常见使用的,基本可以满足日常我们对事物的使用,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 = "/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请求

:8182/api/user/test1

Body参数为:

{"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请求

:8182/api/user/test1

Body参数为:

{"id":1,"name":"xuwujing","age":18}

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsxpyw.html