美文网首页
Spring Boot 配置与注解

Spring Boot 配置与注解

作者: Minnakey | 来源:发表于2020-04-19 19:43 被阅读0次

    . Spring 是一个“引擎”;
    . Spring MVC 是基于Spring的一个 MVC 框架;
    . Spring Boot 是基于Spring4的条件注册的一套快速开发整合包。

    整理自:
    https://mp.weixin.qq.com/s/nOx6iRfhPWWl2vKTSQ52Hg
    https://mp.weixin.qq.com/s/ztM0VRgSLUZMK4sZ4rVFwA
    https://mp.weixin.qq.com/s/OaMaT-QF20P65tKOjC5_oA

    Spring Boot 自动配置

    • IOC
    • MVC
    • mybatis
    • mybatis plus

    注解

    • 注解(annotations)列表
    • 注解(annotations)详解
    • JPA注解
    • springMVC相关注解
    • 全局异常处理
    • mybatis-plus常用注解
    • @Transactional

    Spring Boot 怎么做自动配置的?

    SpringBoot自动配置

    从代码里看项目SpringBoot的项目启动类只有一个注解@SpringBootApplication和一个run方法。

    @SpringBootApplicationpublic 
    class Application {    
    public static void main(String[] args) {        
        SpringApplication.run(Application.class, args);    
    }}
    

    @SpringBootApplication:包含了@SpringBootConfiguration(打开是@Configuration),@EnableAutoConfiguration,@ComponentScan注解。

    • @Configuration 等同于spring的XML配置文件;使用Java代码可以检查类型安全。
    • @EnableAutoConfiguration 自动配置。
    • @ComponentScan 让spring Boot扫描到Configuration类并把它加入到程序上下文,可自动发现和装配一些Bean。

    1. @Configuration

    用一个过滤器举例,JavaConfig的配置方式是这样

    @Configurationpublic 
    class DruidConfiguration {        
        @Bean    
         public FilterRegistrationBean statFilter(){       
             //创建过滤器        
               FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());        
              //设置过滤器过滤路径        
               filterRegistrationBean.addUrlPatterns("/*");        
              //忽略过滤的形式        
               filterRegistrationBean.addInitParameter("exclusions","*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");        
               return filterRegistrationBean;   
     }}
    

    任何一个标注了@Configuration的Java类定义都是一个JavaConfig配置类。
    任何一个标注了@Bean的方法,其返回值将作为一个bean定义注册到Spring的IoC容器,方法名将默认成该bean定义的id。

    2. @ComponentScan

    @ComponentScan对应XML配置中的元素,@ComponentScan的功能其实就是自动扫描并加载符合条件的组件(比如@Component和@Repository等)或者bean定义,最终将这些bean定义加载到IoC容器中。
    我们可以通过basePackages等属性来细粒度的定制@ComponentScan自动扫描的范围,如果不指定,则默认Spring框架实现会从声明@ComponentScan所在类的package进行扫描。
    注:所以SpringBoot的启动类最好是放在rootpackage下,因为默认不指定basePackages。

    3. @EnableAutoConfiguration

    借助@Import的帮助,将所有符合自动配置条件的bean定义加载到IoC容器。

    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @AutoConfigurationPackage
    @Import({AutoConfigurationImportSelector.class})
    public @interface EnableAutoConfiguration {    
      String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
           Class<?>[] exclude() default {};
           String[] excludeName() default {};
    }
    

    @Import(EnableAutoConfigurationImportSelector.class),借助EnableAutoConfigurationImportSelector,@EnableAutoConfiguration可以帮助SpringBoot应用将所有符合条件的@Configuration配置都加载到当前SpringBoot创建并使用的IoC容器。该配置模块的主要使用到了SpringFactoriesLoader
    SpringFactoriesLoader: 类加载器,spring.factories文件,文件中对应的类则是接口的实现类
    AutoConfigurationImportSelector: ImportSelector在springboot启动流程——bean实例化前被执行,返回要实例化的类信息列表,类信息加载到 JVM。

    4. IOC

    理论:控制反转,控制权的转移,应用程序本身不负责依赖对象的创建和维护,而是由外部容器负责创建和维护。
    ​   ●谁依赖于谁:当然是应用程序依赖于IoC容器;
    ​   ●为什么需要依赖:应用程序需要IoC容器来提供对象需要的外部资源;
    ​   ●谁注入谁:很明显是IoC容器注入应用程序某个对象,应用程序依赖的对象;
    ​   ●注入了什么:就是注入某个对象所需要的外部资源(包括对象、资源、常量数据)。
    目的:创建对象并且组装对象之间的关系
    BeanApplication容器
    ​   ●org.springframework.beans : BeanFactroy提供配置结构和基本功能,加载并初始化Bean
    ​   ●org.springframework.context :ApplicationContext保存了Bean对象并在Spring中被广泛使用
    ​   ●标签: @Component、@Repository、@Service、@Controller、@Autowired
    ​   ●注入方式:属性注入、构造器注入
    ​   ●初始化方式:文件、Classpath,Web应用

    5. MVC

    主要组件:前端控制器DispatcherServlet、处理器映射器HandlerMapping、处理器适配器HandlerAdapter、处理器Handler(需要工程师开发)、视图解析器View resolver(jstlView、freemarkerView、pdfView)

    6. MyBatis

    Maven:依赖starter就可以依赖到所有需要自动配置的类,实现开箱即用的功能
    MyBatis 支持定制化 SQL、存储过程以及高级映射:
    ​   ●MyBatis使用SqlSessionFactoryBuilder来完成连接
    ​   ●MyBatis可以将SQL代码写入xml中,使用简单的 XML 或注解来配置和映射原生信息
    ​   ●MyBatis的mapper会自动将执行后的结果映射到对应的Java对象中,映射成数据库中的记录
    组件:SqlSessionFactoryBuilder连接数据库、SqlSessionFactory数据源、SqlSession增删改查方法
    缺点: SQL 工作量大

    7. mybatis plus

    特性:
      ●无侵入:Mybatis 的增强工具,只做增强不做改变;
      ●依赖少:仅仅依赖 Mybatis 以及 Mybatis-Spring,
      ●损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
      ●预防Sql注入:内置 Sql 注入剥离器,有效预防Sql注入攻击
      ●通用CRUD操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
      ●多种主键策略:支持多达4种主键策略(内含分布式唯一ID生成器),可自由配置,完美解决主键问题
      ●支持热加载:Mapper 对应的 XML 支持热加载,对于简单的 CRUD 操作,甚至可以无 XML 启动
      ●支持ActiveRecord:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可实现基本 CRUD 操作Active Record 是一种数据访问设计模式,它可以帮助你实现数据对象Object到关系数据库的映射。
      ●支持代码生成:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用(P.S. 比 Mybatis 官方的 Generator 更加强大!)
      ●支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
      ●支持关键词自动转义:支持数据库关键词(order、key......)自动转义,还可自定义关键词
      ●内置分页插件:基于 Mybatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通List查询
      ●内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能有效解决慢查询
      ●内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,预防误操作

    注解

    1、注解(annotations)列表

    1. @SpringBootApplication
      包含了@ComponentScan、@Configuration和@EnableAutoConfiguration注解。
      其中@ComponentScan让spring Boot扫描到Configuration类并把它加入到程序上下文。

    2. @Component 可配合CommandLineRunner使用,在程序启动后执行一些基础任务。

    3. @RestController注解是@Controller和@ResponseBody的合集,表示这是个控制器bean,并且是将函数的返回值直 接填入HTTP响应体中,是REST风格的控制器。

    4. @Autowired自动导入。

    5. @PathVariable获取参数。

    6. @JsonBackReference解决嵌套外链问题。

    7. @RepositoryRestResourcepublic配合spring-boot-starter-data-rest使用。

    2、注解(annotations)详解

    • @SpringBootApplication:申明让spring boot自动给程序进行必要的配置,这个配置等同于:@Configuration ,@EnableAutoConfiguration 和 @ComponentScan 三个配置。
    package com.example.myproject;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication // same as @Configuration @EnableAutoConfiguration @ComponentScan
    public class Application {
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    }
    
    • @ResponseBody:表示该方法的返回结果直接写入HTTP response body中,一般在异步获取数据时使用,用于构建RESTful的api。
      在使用@RequestMapping后,返回值通常解析为跳转路径,加上@responsebody后返回结果不会被解析为跳转路径,而是直接写入HTTP response body中。
      比如异步获取json数据,加上@responsebody后,会直接返回json数据。
      该注解一般会配合@RequestMapping一起使用。示例代码:
    @ResponseBody
    public String test(){
        return”ok”;
    }
    
    • @Controller:用于定义控制器类,在spring 项目中由控制器负责将用户发来的URL请求转发到对应的服务接口(service层)
      一般这个注解在类中,通常方法需要配合注解@RequestMapping。
      示例代码:
    @Controller
    @RequestMapping(“/demoInfo”)
    publicclass DemoController {
        @Autowired
        private DemoInfoService demoInfoService;
    
        @RequestMapping("/hello")
        public String hello(Map map){
            System.out.println("DemoController.hello()");
            map.put("hello","from TemplateController.helloHtml");
            //会使用hello.html或者hello.ftl模板进行渲染显示.
            return"/hello";
        }
    }
    
    • @RestController:用于标注控制层组件(如struts中的action),@ResponseBody和@Controller的合集。
      示例代码:
    package com.kfit.demo.web;
    
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @RequestMapping(“/demoInfo2”)
    publicclass DemoController2 {
    
        @RequestMapping("/test")
        public String test(){
            return"ok";
        }
    }
    
    • @RequestMapping:提供路由信息,负责URL到Controller中的具体函数的映射。
    • @EnableAutoConfiguration:Spring Boot自动配置(auto-configuration):尝试根据你添加的jar依赖自动配置你的Spring应用。
      例如,如果你的classpath下存在HSQLDB,并且你没有手动配置任何数据库连接beans,那么我们将自动配置一个内存型(in-memory)数据库”。
      你可以将@EnableAutoConfiguration或者@SpringBootApplication注解添加到一个@Configuration类上来选择自动配置。
      如果发现应用了你不想要的特定自动配置类,你可以使用@EnableAutoConfiguration注解的排除属性来禁用它们。
    • @ComponentScan:表示将该类自动发现扫描组件。
      个人理解相当于,如果扫描到有@Component、@Controller、@Service等这些注解的类,并注册为Bean,可以自动收集所有的Spring组件,包括@Configuration类。
      我们经常使用@ComponentScan注解搜索beans,并结合@Autowired注解导入。可以自动收集所有的Spring组件,包括@Configuration类。
      如果没有配置的话,Spring Boot会扫描启动类所在包下以及子包下的使用了@Service,@Repository等注解的类。
    • @Configuration:相当于传统的xml配置文件,如果有些第三方库需要用到xml文件,建议仍然通过@Configuration类作为项目的配置主类——可以使用@ImportResource注解加载xml配置文件。
    • @Import:用来导入其他配置类。
    • @ImportResource:用来加载xml配置文件。
    • @Autowired:自动导入依赖的bean
    • @Service:一般用于修饰service层的组件
    • @Repository:使用@Repository注解可以确保DAO或者repositories提供异常转译,这个注解修饰的DAO或者repositories类会被ComponetScan发现并配置,同时也不需要为它们提供XML配置项。
    • @Bean:用@Bean标注方法等价于XML中配置的bean。
    • @Value:注入Spring boot application.properties配置的属性的值。示例代码:
    @Value(value = “#{message}”)
    private String message;
    
    • @Inject:等价于默认的@Autowired,只是没有required属性;
    • @Component:泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
    • @Bean:相当于XML中的,放在方法的上面,而不是类,意思是产生一个bean,并交给spring管理。
    • @AutoWired:自动导入依赖的bean。byType方式。把配置好的Bean拿来用,完成属性、方法的组装,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。当加上(required=false)时,就算找不到bean也不报错。
    • @Qualifier:当有多个同一类型的Bean时,可以用@Qualifier(“name”)来指定。与@Autowired配合使用。@Qualifier限定描述符除了能根据名字进行注入,但能进行更细粒度的控制如何选择候选者,具体使用方式如下:
    @Autowired
    @Qualifier(value = “demoInfoService”)
    private DemoInfoService demoInfoService;
    
    • @Resource(name=”name”,type=”type”):没有括号内内容的话,默认byName。与@Autowired干类似的事。

    3、JPA注解

    • @Entity:@Table(name=”“):表明这是一个实体类。一般用于jpa这两个注解一般一块使用,但是如果表名和实体类名相同的话,@Table可以省略
    • @MappedSuperClass:用在确定是父类的entity上。父类的属性子类可以继承。
    • @NoRepositoryBean:一般用作父类的repository,有这个注解,spring不会去实例化该repository。
    • @Column:如果字段名与列名相同,则可以省略。
    • @Id:表示该属性为主键。
    • @GeneratedValue(strategy=GenerationType.SEQUENCE,generator= “repair_seq”):表示主键生成策略是sequence(可以为Auto、IDENTITY、native等,Auto表示可在多个数据库间切换),指定sequence的名字是repair_seq。
    • @SequenceGeneretor(name = “repair_seq”, sequenceName = “seq_repair”, allocationSize = 1):name为sequence的名称,以便使用,sequenceName为数据库的sequence名称,两个名称可以一致。
    • @Transient:表示该属性并非一个到数据库表的字段的映射,ORM框架将忽略该属性。
      如果一个属性并非数据库表的字段映射,就务必将其标示为@Transient,否则,ORM框架默认其注解为@Basic。@Basic(fetch=FetchType.LAZY):标记可以指定实体属性的加载方式
    • @JsonIgnore:作用是json序列化时将Java bean中的一些属性忽略掉,序列化和反序列化都受影响。
    • @JoinColumn(name=”loginId”):一对一:本表中指向另一个表的外键。一对多:另一个表指向本表的外键。
    • @OneToOne、@OneToMany、@ManyToOne:对应hibernate配置文件中的一对一,一对多,多对一。

    4、springMVC相关注解

    • @RequestMapping:@RequestMapping(“/path”)表示该控制器处理所有“/path”的UR L请求。
      RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。
      用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。该注解有六个属性:
      params:指定request中必须包含某些参数值是,才让该方法处理。
      headers:指定request中必须包含某些指定的header值,才能让该方法处理请求。
      value:指定请求的实际地址,指定的地址可以是URI Template 模式
      method:指定请求的method类型, GET、POST、PUT、DELETE等
      consumes:指定处理请求的提交内容类型(Content-Type),如application/json,text/html;
      produces:指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回
    • @RequestParam:用在方法的参数前面。
    @RequestParam
    String a =request.getParameter(“a”)。
    @PathVariable:路径变量。如
    RequestMapping(“user/get/mac/{macAddress}”)
    public String getByMacAddress(@PathVariable String macAddress){
        //do something;
    }参数与大括号里的名字一样要相同。
    

    5、mybatis-plus常用注解

    • 表名注解@TableName
    • 主键注解@Tabeld
    • 乐观锁标记注解@Version
    • 字段注解@TableField
    • 序列主键策略注解@KeySequence
    • 当数据库的表字段名是驼峰命名时无需注解处理
    • 或者全局配置: 下划线命名 dbColumnUnderline 设置 true , 大写 isCapitalMode 设置 true

    6、全局异常处理

    • @ControllerAdvice:包含@Component。可以被扫描到。统一处理异常。
    • @ExceptionHandler(Exception.class):用在方法上面表示遇到这个异常就执行以下方法。

    7、@Transactional 注解六种失效场景

    1. 事务

    事务管理在系统开发中是不可缺少的一部分,Spring提供了很好事务管理机制,主要分为编程式事务和声明式事务两种。
    编程式事务:是指在代码中手动的管理事务的提交、回滚等操作,代码侵入性比较强,如下示例:

    try {
        //TODO something
         transactionManager.commit(status);
    } catch (Exception e) {
        transactionManager.rollback(status);
        throw new InvoiceApplyException("异常失败");
    }
    

    声明式事务:基于AOP面向切面的,它将具体业务与事务处理部分解耦,代码侵入性很低,所以在实际开发中声明式事务用的比较多。声明式事务也有两种实现方式,一是基于TX和AOP的xml配置文件方式,二种就是基于@Transactional注解了。

       @Transactional
       @GetMapping("/test")
        public String test() {
            int insert = cityInfoDictMapper.insert(cityInfoDict);
        }
    
    2. @Transactional介绍

    1)、@Transactional注解可以作用于哪些地方?
    @Transactional 可以作用在接口、类、类方法。

    • 作用于类:当把@Transactional 注解放在类上时,表示所有该类的public方法都配置相同的事务属性信息。
    • 作用于方法:当类配置了@Transactional,方法也配置了@Transactional,方法的事务会覆盖类的事务配置信息。
    • 作用于接口:不推荐这种使用方法,因为一旦标注在Interface上并且配置了Spring AOP 使用CGLib动态代理,将会导致@Transactional注解失效
     @Transactional
     @RestController
     @RequestMapping
     public class MybatisPlusController {
        @Autowired
         private CityInfoDictMapper cityInfoDictMapper;
     
         @Transactional(rollbackFor = Exception.class)
         @GetMapping("/test")
        public String test() throws Exception {
            CityInfoDict cityInfoDict = new CityInfoDict();
            cityInfoDict.setParentCityId(2);
           cityInfoDict.setCityName("2");
            cityInfoDict.setCityLevel("2");
           cityInfoDict.setCityCode("2");
            int insert = cityInfoDictMapper.insert(cityInfoDict);
            return insert + "";
        }
    }
    

    2)、@Transactional注有哪些属性?

    propagation 代表事务的传播行为,默认值为 Propagation.REQUIRED,其他的属性信息如下:

    • Propagation.REQUIRED:如果当前存在事务,则加入该事务,如果当前不存在事务,则创建一个新的事务。( 也就是说如果A方法和B方法都添加了注解,在默认传播模式下,A方法内部调用B方法,会把两个方法的事务合并为一个事务 )
    • Propagation.SUPPORTS:如果当前存在事务,则加入该事务;如果当前不存在事务,则以非事务的方式继续运行。
    • Propagation.MANDATORY:如果当前存在事务,则加入该事务;如果当前不存在事务,则抛出异常。
    • Propagation.REQUIRES_NEW:重新创建一个新的事务,如果当前存在事务,暂停当前的事务。( 当类A中的 a 方法用默认Propagation.REQUIRED模式,类B中的 b方法加上采用 Propagation.REQUIRES_NEW模式,然后在 a 方法中调用 b方法操作数据库,然而 a方法抛出异常后,b方法并没有进行回滚,因为Propagation.REQUIRES_NEW会暂停 a方法的事务 )
    • Propagation.NOT_SUPPORTED:以非事务的方式运行,如果当前存在事务,暂停当前的事务。
    • Propagation.NEVER:以非事务的方式运行,如果当前存在事务,则抛出异常。
    • Propagation.NESTED :和 Propagation.REQUIRED 效果一样。

    isolation :事务的隔离级别,默认值为 Isolation.DEFAULT。

    • Isolation.DEFAULT:使用底层数据库默认的隔离级别。
    • Isolation.READ_UNCOMMITTED
    • Isolation.READ_COMMITTED
    • Isolation.REPEATABLE_READ
    • Isolation.SERIALIZABLE

    timeout :事务的超时时间,默认值为 -1。如果超过该时间限制但事务还没有完成,则自动回滚事务。
    readOnly :指定事务是否为只读事务,默认值为 false;为了忽略那些不需要事务的方法,比如读取数据,可以设置 read-only 为 true。
    rollbackFor :用于指定能够触发事务回滚的异常类型,可以指定多个异常类型。
    noRollbackFor:抛出指定的异常类型,不回滚事务,也可以指定多个异常类型。

    3. @Transactional失效场景

    1). @Transactional 应用在非 public 修饰的方法上
    因为在Spring AOP 代理时,TransactionInterceptor (事务拦截器)在目标方法执行前后进行拦截,DynamicAdvisedInterceptor(CglibAopProxy 的内部类)的 intercept 方法或 JdkDynamicAopProxy 的 invoke 方法会间接调用 AbstractFallbackTransactionAttributeSource的 computeTransactionAttribute 方法,获取Transactional 注解的事务配置信息。

    protected TransactionAttribute computeTransactionAttribute(Method method,
        Class<?> targetClass) {
            // Don't allow no-public methods as required.
            if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
            return null;
    }
    

    此方法会检查目标方法的修饰符是否为 public,不是 public则不会获取@Transactional 的属性配置信息。
    注意:protected、private 修饰的方法上使用 @Transactional 注解,虽然事务无效,但不会有任何报错,这是我们很容犯错的一点。

    2). @Transactional 注解属性 propagation 设置错误
    这种失效是由于配置错误,若是错误的配置以下三种 propagation,事务将不会发生回滚。

    • TransactionDefinition.PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
    • TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起。
    • TransactionDefinition.PROPAGATION_NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。

    3). @Transactional 注解属性 rollbackFor 设置错误
    rollbackFor 可以指定能够触发事务回滚的异常类型。Spring默认抛出了未检查unchecked异常(继承自 RuntimeException的异常)或者 Error才回滚事务;其他异常不会触发回滚事务。如果在事务中抛出其他类型的异常,但却期望 Spring 能够回滚事务,就需要指定 rollbackFor属性。

    4). 同一个类中方法调用,导致@Transactional失效
    开发中避免不了会对同一个类里面的方法调用,比如有一个类Test,它的一个方法A,A再调用本类的方法B(不论方法B是用public还是private修饰),但方法A没有声明注解事务,而B方法有。则外部调用方法A之后,方法B的事务是不会起作用的。这也是经常犯错误的一个地方。

    那为啥会出现这种情况?其实这还是由于使用Spring AOP代理造成的,因为只有当事务方法被当前类以外的代码调用时,才会由Spring生成的代理对象来管理。

    5). 异常被你的 catch“吃了”导致@Transactional失效
    如果B方法内部抛了异常,而A方法此时try catch了B方法的异常,那这个事务还能正常回滚吗?
    答案:不能!
    会抛出异常:
    org.springframework.transaction.UnexpectedRollbackException: Transaction rolle
    因为当ServiceB中抛出了一个异常以后,ServiceB标识当前事务需要rollback。但是ServiceA中由于你手动的捕获这个异常并进行处理,ServiceA认为当前事务应该正常commit。此时就出现了前后不一致,也就是因为这样,抛出了前面的UnexpectedRollbackException异常。

    spring的事务是在调用业务方法之前开始的,业务方法执行完毕之后才执行commit or rollback,事务是否执行取决于是否抛出runtime异常。如果抛出runtime exception 并在你的业务方法中没有catch到的话,事务会回滚。

    在业务方法中一般不需要catch异常,如果非要catch一定要抛出throw new RuntimeException(),或者注解中指定抛异常类型@Transactional(rollbackFor=Exception.class),否则会导致事务失效,数据commit造成数据不一致,所以有些时候try catch反倒会画蛇添足。

    6). 数据库引擎不支持事务
    这种情况出现的概率并不高,事务能否生效数据库引擎是否支持事务是关键。常用的MySQL数据库默认使用支持事务的innodb引擎。一旦数据库引擎切换成不支持事务的myisam,那事务就从根本上失效了。

    相关文章

      网友评论

          本文标题:Spring Boot 配置与注解

          本文链接:https://www.haomeiwen.com/subject/wlpybhtx.html