您现在的位置是:主页 > news > 高校廉洁文化建设网站/seo诊断分析报告

高校廉洁文化建设网站/seo诊断分析报告

admin2025/4/22 4:42:35news

简介高校廉洁文化建设网站,seo诊断分析报告,网站建设会议纪要,技术文章目录概述1. 非异常用例1.1 创建工程1.2 执行2. 内层抛出非check异常,外层进行捕获3. 内层抛出非check异常,外层不进行捕获相关文章spring 的事务(transaction) 一 基础概念介绍spring 的事务(transaction) 二 陷阱spring 的事务(transaction) 三 try…

高校廉洁文化建设网站,seo诊断分析报告,网站建设会议纪要,技术文章目录概述1. 非异常用例1.1 创建工程1.2 执行2. 内层抛出非check异常,外层进行捕获3. 内层抛出非check异常,外层不进行捕获相关文章spring 的事务(transaction) 一 基础概念介绍spring 的事务(transaction) 二 陷阱spring 的事务(transaction) 三 try…

文章目录

  • 概述
  • 1. 非异常用例
    • 1.1 创建工程
    • 1.2 执行
  • 2. 内层抛出非check异常,外层进行捕获
  • 3. 内层抛出非check异常,外层不进行捕获

相关文章
spring 的事务(transaction) 一 基础概念介绍
spring 的事务(transaction) 二 陷阱
spring 的事务(transaction) 三 try catch对事务的影响
spring 的事务(transaction) 四 嵌套事务PROPAGATION_NESTED

概述

外层事务和内层事务基础概念知晓后,需要结合try catch才能真正理解,因为try catch会影响异常的传递。

本篇文章强调了外层和内存,以Propagation.REQUIRED+Propagation.REQUIRED为例,看过前面《spring 的事务(transaction) 一 基础概念介绍》一文的话,知道这二者是独立事务,而不是父子事务。针对父子事务,会单独写篇文章来介绍。

try catch可以加在内层,也可以在外层。 虽然外层和内存

1. 非异常用例

我们开始一个经典的嵌套用例。

1.1 创建工程

我们先创建一个spring的工程,利用spring 单元测试架构,来写用例

工程的创建参见 用SpringBoot创建mysql工程,后续以该工程为基础改造用例。

数据库脚本,新增一个:

CREATE TABLE `order` (`id` INT(11) NOT NULL,`price` VARCHAR(10) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8INSERT INTO `order` (`id`, `price`) VALUES(1,'100');
INSERT INTO `order` (`id`, `price`) VALUES(2,'150');

项目整体视图:

在这里插入图片描述
MysqldemoApplication:

package com.example.mysqldemo;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.transaction.annotation.EnableTransactionManagement;@SpringBootApplication
@ComponentScan("com.example")   //设置扫描路径
@EnableTransactionManagement   //开启事务
public class MysqldemoApplication {public static void main(String[] args) {SpringApplication.run(MysqldemoApplication.class, args);}}

定义2个接口,分别是IOrderService和IUserService:

package com.example.service;public interface IOrderService {public void  addOrder(int id, String name);}
package com.example.service;public interface IUserService {public void  addUser(int id, String name);}

定义2个实现类:

package com.example.service;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;@Service
public class OrderServiceImpl implements IOrderService {@Autowiredprivate JdbcTemplate jdbcTemplate;@Transactional(propagation = Propagation.REQUIRES_NEW)@Overridepublic void addOrder(int id, String price) {//order是mysql关键词,必须用`号(tab键上方的那个键,波浪线键)包裹起来jdbcTemplate.execute("insert into `order` values ("+id+",'"+price+"')");}
}
package com.example.service;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;@Service
public class UserServiceImpl implements IUserService {@Autowiredprivate JdbcTemplate jdbcTemplate;@Autowiredprivate IOrderService orderService;@Transactional(propagation = Propagation.REQUIRES_NEW)@Overridepublic void addUser(int id, String name) {jdbcTemplate.execute("insert into `student` values (" + id + ",'" + name + "')");try {//注意:此时有try catchorderService.addOrder(3, "110");} catch (Exception e) {System.out.println(e);}}}

application.properties:

#集成mysql数据库的配置
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://10.40.65.183:3306/test
spring.datasource.username=
spring.datasource.password=

测试用例:

package com.example.mysqldemo;import com.example.service.IUserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.junit4.SpringRunner;@RunWith(SpringRunner.class)
@SpringBootTest(classes = MysqldemoApplication.class)
public class MysqldemoApplicationTests {@Autowiredprivate IUserService userService ;@Testpublic void insert() {userService.addUser(4,"hanmeimei");}}

此时我们在此时用例中插入一个用户数据,而在内部,会插入一个订单信息。

如果数据库存在脏数据,可以先清除脏数据。

1.2 执行

执行后,数据都是正常插入的,原因是没有任何异常出现:
在这里插入图片描述
注意:此时addUser()内有try catch,这是标准用法:

    public void addUser(int id, String name) {jdbcTemplate.execute("insert into `student` values (" + id + ",'" + name + "')");try {orderService.addOrder(3, "110");} catch (Exception e) {System.out.println(e);}}

2. 内层抛出非check异常,外层进行捕获

结论:符合预期,内层回滚,外层不回滚。内层抛出非check异常,自动帮我们回滚内层事务,外层捕获内层异常,避免异常传递至外层,外层不回滚。

注意:我们定义的外层和内存事务都是REQUIRES_NEW,如果是其他事务,又是另一个结论。

我们模拟在orderservice.addOrder()内抛出一个ArithmeticException异常,这是个非check异常。

按照预期,内层事务出现非check异常,会自动回滚,而外层没有出现错误,不会回滚。

   System.out.println( 1/0);

在这里插入图片描述
重新执行:
在这里插入图片描述
总结:

  • 内层事务抛出非check异常,并且内部没有try catch,这样内层声明的事务能捕获该异常,自动帮我们回滚内层事务
  • 外层自身没有抛出异常,并且通过try catch ,捕获了内层异常,使得内部异常没有传递到外层,外层等价于没有异常,不会回滚

在这里插入图片描述

3. 内层抛出非check异常,外层不进行捕获

在2章节里面,我们就强调过 外层没有加try catch时,内存抛出异常后,会导致异常传递至外层,引发外层也回滚

下面我们来验证下上述结论:

注释掉外层方法的try catch:

    public void addUser(int id, String name) {jdbcTemplate.execute("insert into `student` values (" + id + ",'" + name + "')");orderService.addOrder(3, "110");

我们来验证下,确实都没有出现新增的数据:
在这里插入图片描述
过程分析:
在这里插入图片描述