废话前言
暂时不讲理论先尝试…
1. 启动类添加注解@EnableTransactionManagement开启事物:
@SpringBootApplication
@EnableTransactionManagement
@MapperScan("com.sfc.sso_server.dao.interfaces")
public class SsoServerApplication {
public static void main(String[] args) {
SpringApplication.run(SsoServerApplication.class, args);
}
}
2. Controller层
controller层的@Transactional可加可不加看具体案例
@Slf4j
@RestController
//@Controller(RestController表示本类下的方法都是直接做内容返回到浏览器Controller用于控制层)
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping(value = "/insertUser", method = RequestMethod.GET)
public void insertUser(){
log.info(">>>>>>insert start..");
User user = new User();
user.setUsername("小明");
user.setAge(20);
user.setAddress("上海");
user.setUserpassword("admin");
int count = userService.insertUser(user);
}
3. service层代码
正常代码执行成功。
@Override
@Transactional
public int insertUser(User user) {
int count = userMapper.insert(user);
log.info(">>>>>插入数据:{}条!",count);
return count;
}
开始测试案例
1.抛出模拟抛出RuntimeException异常: 模拟到异常事物回滚数据未插入。
@Override
@Transactional
public int insertUser(User user) {
int count = userMapper.insert(user);
log.info(">>>>>插入数据:{}条!",count);
if(1==1) {
throw new RuntimeException("故意报错");
}
return count;
}
2.抛出模拟抛出Exception异常controller和service都抛出如下
public int insertUser(User user) throws Exception {
public void insertUser() throws Exception {
(这个时候出问题了数据正常保存上了并没有回滚。尝试抛出指定异常。@Transactional(rollbackFor = Exception.class)这样注解指定异常类型事物回滚了)
3.在controller加上异常捕获事物回滚了。
@Transactional
@RequestMapping(value = "/insertUser", method = RequestMethod.GET)
public void insertUser() throws Exception {
log.info(">>>>>>insert start..");
User user = new User();
user.setUsername("小明");
user.setAge(20);
user.setAddress("上海");
user.setUserpassword("admin");
try{
int count = userService.insertUser(user);
}catch (Exception e){
log.info(">>>>>>insert error.",e.getMessage(),e);
}
}
4.在service加上异常捕获事物被吃掉不生效。
@Override
@Transactional(rollbackFor = Exception.class)
public int insertUser(User user) throws Exception {
int count = 0;
try{
count = userMapper.insert(user);
log.info(">>>>>插入数据:{}条!",count);
if(1==1) {
throw new Exception("故意报错");
}
}catch (Exception e){
log.info(">>>>>>insert error.",e.getMessage(),e);
}
return count;
}
- 嵌套service,在service中调用本类中的service事物测试
事物正常回滚了,两条都没添加成功。
@Override
@Transactional(rollbackFor = Exception.class)
public int insertUser(User user) throws Exception {
int count = userMapper.insert(user);
log.info(">>>>>插入数据:{}条!",count);
this.insertUser2(user);
return count;
}
public int insertUser2(User user) throws Exception {
int count = userMapper.insert(user);
log.info(">>>>>插入数据:{}条!",count);
if(1==1) {
throw new Exception("故意报错");
}
return count;
}
- 事物只在controller层会不会回滚
这里如果controller加上异常捕获事物就会被吃掉,不管是指定异常类型还是不指定异常。
如果service抛出Exception异常就要指定,默认是回滚RuntimeException异常。
- 如果我只回滚嵌套最深的service怎么实现
1.controller和service去掉事物,只在service调用的service(抛异常加事物)----(两条都插入)
2.controller去掉事物,只在service(加事物)调用的service(抛异常)----(两条都回滚)
3.controller去掉事物,只在service(加事物抛异常)调用的service----(两条都回滚)