例如:用户A付钱给用户B,那么用户A的账户需被扣钱。所扣的钱需被加到用户B的账户上;
但是在项目中,我们的代码走向是,先扣除了用户A的账户钱,这个时候,数据已经被写入SQL中,并且被提交,如果这个时候出现代码错误,无法往下继续走时,会导致,用户B并没有获取到本该增加的钱,其实这个时候很容易出现问题
这个时候就需要引入@Transactional事务管理;将这个注解放置在所需要的放置的service层的对应方法上;
这个时候,@Transactional将会作用于该方法上,@Transactional注解是将方法体内执行的代码。先预先暂存在一个地方;
队友只有当方法内的代码全部成功走完之后,才会对数据进行成功操作;如果中间出现错误的代码,导致执行不下去时,会将前面已经执行成功的数据,直接false,不会将对应数据提交;
这个一般来说我们会使用在增删改这三个操作的前面加上@Transactional,查询的话,就不需要加上
例如:我们需要更新数据库表中老师的内容:如果在进行更新时,出现错误时,是否会被真的修改掉??
controller层:
package com.cmj.controller;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.cmj.entity.Teacher;
import com.cmj.service.UserService;
import com.github.pagehelper.PageInfo;
@RestController
@RequestMapping(“/teacher”)
public class TeacherController {
@Autowired
private UserService userService;
// 修改老师
@PutMapping(“/update”)
public String update(@RequestBody Teacher teacher) {
return userService.update(teacher);
}
}
2、Mapper数据
TeacherMapper.java
package com.cmj.dao;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import com.cmj.entity.Teacher;
@Mapper
public interface TeacherMapper {
public void updateTeacher(Teacher teacher);
}
TeacherMapper.xml
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
“http://mybatis.org/dtd/mybatis-3-mapper.dtd”>
UPDATE `teacher` SET
`pass_word`=#{passWord}
WHERE (`name`=#{name})
3、service执行代码:
package com.cmj.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.cmj.dao.TeacherMapper;
import com.cmj.entity.Teacher;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
@Service
public class UserService {
@Autowired
private TeacherMapper teacherMapper;
// 修改老师
@Transactional
public String update(Teacher teacher) {
teacherMapper.updateTeacher(teacher);
int i = 1 / 0;
teacherMapper.deleteByName(“nini”);
return “成功”;
}
当我们在修改老师这个方法体上加上 @Transactional注解后,当代码执行时
①、teacherMapper.updateTeacher(teacher);进行更新teacher时,系统不会马上对表中的数据进行更新;而是先存放在一个地方,等待整个方法内的代码执行成功后再进行提交;(如果出现错误,则不会被更新)
②、当代码走到:int i = 1 / 0;时,发现这个是一个错误代码,代码走到这边后,工程停住,无法向下走后,也无法执行到teacherMapper.deleteByName(“nini”)删除老师的代码;
③、当这个方法出现报错时,第一条的teacherMapper.updateTeacher(teacher)也被直接判定为false,这个方法中的内容都不会被执行到
只有当这个方法正常被执行后,才可能被执行
所以这就是@Transactional事务管理的作用