• spring boot事务管理


    spring boot集成事务十分的简单,只需要在启动类上面增加@EnableTransactionManagement注解,然后在需要实现事务的方法上添加@Transactional注解就可以了。下面我们根据上一次的代码来演示下。

    首先,我们修改下启动类

    package com.example.demo;
    
    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.builder.SpringApplicationBuilder;
    import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
    import org.springframework.transaction.annotation.EnableTransactionManagement;
    
    @SpringBootApplication
    @MapperScan(basePackages = ("com.example.demo.mapper"))
    @EnableTransactionManagement//开启springboot事务的支持
    public class DemoApplication extends SpringBootServletInitializer {
    
        @Override
        protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
            return application.sources(DemoApplication.class);
        }
    
        public static void main(String[] args) {
            SpringApplication.run(DemoApplication.class, args);
        }
    
    }

    在service中添加一个修改方法

    package com.example.demo.service;
    
    import com.example.demo.model.Student;
    
    public interface GetStudentService {
    
        public Student getStudentInfo();
    
        public int update();
    }
    package com.example.demo.service.impl;
    
    import com.example.demo.mapper.StudentMapper;
    import com.example.demo.model.Student;
    import com.example.demo.service.GetStudentService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    
    @Service
    public class GetStudentServiceImpl implements GetStudentService {
    
        @Autowired
        private StudentMapper studentMapper;
    
        @Override
        public Student getStudentInfo() {
            Student student = studentMapper.selectByPrimaryKey("122528");
            return student;
        }
    
        @Transactional//增加事务注解
        @Override
        public int update(){
            Student student = new Student();
            student.setId("122528");
            student.setName("李四");
            int ret = studentMapper.updateByPrimaryKey(student);
    
            int i = 100/0; //触发异常,测试更新事件会不会回滚
            return ret;
        }
    }

    在上面的类中特意引发了异常,用于我们的测试。最后在controlle中添加对修改方法的调用。

    package com.example.demo.controller;
    
    import com.example.demo.model.Student;
    import com.example.demo.service.GetStudentService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class GetStudentController {
    
        @Autowired
        private GetStudentService getStudentService;
    
        @RequestMapping("/getStudent")
        public String getStudent(){
            Student student = getStudentService.getStudentInfo();
            return "学号=" + student.getId() + ";姓名=" + student.getName();
        }
    
        @RequestMapping("/updateStudent")
        public String updateStudent(){
            getStudentService.update();
            return "success";
        }
    }

    数据库中原始的姓名是张三,现在将他改为李四,访问地址http://127.0.0.1:8088/demo/updateStudent,最终结果报了异常,然后查看数据库中的值,发现没有发生变化,因此我们的事务注解生效了。


    在上面的操作过程中,我发现了一个问题,在controller中如果使用private GetStudentServiceImpl getStudentServiceImpl;启动的时候就会报错:

    Description:
    
    The bean 'getStudentServiceImpl' could not be injected as a 'com.example.demo.service.impl.GetStudentServiceImpl' because it is a JDK dynamic proxy that implements:
        com.example.demo.service.GetStudentService
    
    
    Action:
    
    Consider injecting the bean as one of its interfaces or forcing the use of CGLib-based proxies by setting proxyTargetClass=true on @EnableAsync and/or @EnableCaching.
    
    
    Process finished with exit code 1

    对此有两种解决方法,一种是我上面的,将代码中的引用由实现类改为接口类即可。另外一种是在开启事务的注解上增加属性。即@EnableTransactionManagement(proxyTargetClass = true),开启CGLIB代理也能解决。

    因为开启事务时,会自动开启动态代理,默认的是开启的jdk动态代理。详细解释地址:https://blog.csdn.net/huang_550/article/details/76492600。这块目前还不清楚什么原理,后面再细研究。

    spring boot热部署配置,增加pom.xml依赖

     <!-- spring boot热部署插件-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
                <scope>true</scope>
                <optional>true</optional>
            </dependency>
  • 相关阅读:
    Layui里的倒计时的使用
    idea springboot启动报SLF4J:Failed to load class “org.slf4j.impl.StaticLoggerBinder”
    软件生存周期及其模型是什么?
    试述软件的概念和特点?软件复用的含义?构件包括哪些?
    一台客户端有三百个客户与三百个客户端有三百个客户对服务器施压,有什么区别?
    在搜索引擎中输入汉字就可以解析到对应的域名,请问如何用LoadRunner进行测试。
    给你一个网站,你如何测试?
    使用SpringBoot Actuator 监控应用
    使用SpringBoot 集成 FastDFS
    使用SpringBoot 上传文件
  • 原文地址:https://www.cnblogs.com/wanghq1994/p/12120548.html
Copyright © 2020-2023  润新知