问题:Spring中存在类A和类B,A中存在方法methodA。B中存在方法methodB1和methodB2。methodB1上不存在Transactional事务管理,也就是没有注解@Transactional。methodB2上存在注解@Transactional。那么方法A调用methodB1,methodB1又调用methodB2。这时如果methodB2抛出异常了。那么事务会回滚吗???
问题复现,代码如下
StudentCtrl
package com.jiyx.test.testspringbootmybatis.ctrl;
import com.jiyx.test.testspringbootmybatis.entity.Student;
import com.jiyx.test.testspringbootmybatis.service.StudentSV;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* auther: jiyx
* date: 2018-12-26.
*/
@RestController
@RequestMapping("/student")
public class SutdentCtrl {
@Autowired
private StudentSV studentSV;
@GetMapping("/hello")
public String hello() {
return "hello";
}
@GetMapping("/findAll")
public List<Student> findALl() {
return studentSV.findAll();
}
@PostMapping("/add")
public void insert(@RequestBody Student student) {
studentSV.insert(student);
}
}
StudentSV
package com.jiyx.test.testspringbootmybatis.service;
import com.jiyx.test.testspringbootmybatis.entity.Student;
import java.util.List;
/**
* auther: jiyx
* date: 2018-12-26.
*/
public interface StudentSV {
List<Student> findAll();
void insert(Student student);
void insert1(Student student);
}
StudentSVImpl是StudentSV的实现类
package com.jiyx.test.testspringbootmybatis.service.impl;
import com.jiyx.test.testspringbootmybatis.entity.Student;
import com.jiyx.test.testspringbootmybatis.mapper.StudentExample;
import com.jiyx.test.testspringbootmybatis.mapper.StudentMapper;
import com.jiyx.test.testspringbootmybatis.service.StudentSV;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
/**
* auther: jiyx
* date: 2018-12-26.
*/
@Service("studentSV")
public class StudentSVImpl implements StudentSV {
@Autowired
private StudentMapper studentMapper;
@Override
public List<Student> findAll() {
return studentMapper.selectByExample(new StudentExample());
}
@Override
// @Transactional(rollbackFor = RuntimeException.class)
public void insert(Student student) {
this.insert1(student);
}
@Override
@Transactional(rollbackFor = RuntimeException.class)
public void insert1(Student student) {
studentMapper.insert(student);
throw new RuntimeException("回滚吗?");
}
}
结论:
经测试,方法调用链是A->B1->B2的时候,是不能够产生管理事务的,所以就算抛出异常也不能回滚。
原因:
因为spring的事务调用是基于AOP的,而同一个类中的方法调用是不会走aop的。具体原因可以查看源码。推荐一个博客吧
解决方法:
方式一:在B1上直接加上注解@Transactional
方式二:在启动类上,加上配置@EnableAspectJAutoProxy(exposeProxy = true),然后再B1中使用(StudentSV)AopContext.currentProxy()进行调用。
方式二如图:
启动类注解配置
B1修改
网友评论