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>
原文地址:https://www.cnblogs.com/wanghq1994/p/12120548.html
时间: 2024-11-05 22:37:39