項(xiàng)目中,很多時(shí)候數(shù)據(jù)是相對(duì)的,
例如:用戶A付錢給用戶B,那么用戶A的賬戶需被扣錢。所扣的錢需被加到用戶B的賬戶上;
但是在項(xiàng)目中,我們的代碼走向是,先扣除了用戶A的賬戶錢,這個(gè)時(shí)候,數(shù)據(jù)已經(jīng)被寫入SQL中,并且被提交,如果這個(gè)時(shí)候出現(xiàn)代碼錯(cuò)誤,無(wú)法往下繼續(xù)走時(shí),會(huì)導(dǎo)致,用戶B并沒(méi)有獲取到本該增加的錢,其實(shí)這個(gè)時(shí)候很容易出現(xiàn)問(wèn)題
這個(gè)時(shí)候就需要引入@Transactional事務(wù)管理;將這個(gè)注解放置在所需要的放置的service層的對(duì)應(yīng)方法上;
這個(gè)時(shí)候,@Transactional將會(huì)作用于該方法上,@Transactional注解是將方法體內(nèi)執(zhí)行的代碼。先預(yù)先暫存在一個(gè)地方;
隊(duì)友只有當(dāng)方法內(nèi)的代碼全部成功走完之后,才會(huì)對(duì)數(shù)據(jù)進(jìn)行成功操作;如果中間出現(xiàn)錯(cuò)誤的代碼,導(dǎo)致執(zhí)行不下去時(shí),會(huì)將前面已經(jīng)執(zhí)行成功的數(shù)據(jù),直接false,不會(huì)將對(duì)應(yīng)數(shù)據(jù)提交;
這個(gè)一般來(lái)說(shuō)我們會(huì)使用在增刪改這三個(gè)操作的前面加上@Transactional,查詢的話,就不需要加上
例如:我們需要更新數(shù)據(jù)庫(kù)表中老師的內(nèi)容:如果在進(jìn)行更新時(shí),出現(xiàn)錯(cuò)誤時(shí),是否會(huì)被真的修改掉??
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數(shù)據(jù)
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執(zhí)行代碼:
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 “成功”;
}
當(dāng)我們?cè)谛薷睦蠋熯@個(gè)方法體上加上 @Transactional注解后,當(dāng)代碼執(zhí)行時(shí)
①、teacherMapper.updateTeacher(teacher);進(jìn)行更新teacher時(shí),系統(tǒng)不會(huì)馬上對(duì)表中的數(shù)據(jù)進(jìn)行更新;而是先存放在一個(gè)地方,等待整個(gè)方法內(nèi)的代碼執(zhí)行成功后再進(jìn)行提交;(如果出現(xiàn)錯(cuò)誤,則不會(huì)被更新)
②、當(dāng)代碼走到:int i = 1 / 0;時(shí),發(fā)現(xiàn)這個(gè)是一個(gè)錯(cuò)誤代碼,代碼走到這邊后,工程停住,無(wú)法向下走后,也無(wú)法執(zhí)行到teacherMapper.deleteByName(“nini”)刪除老師的代碼;
③、當(dāng)這個(gè)方法出現(xiàn)報(bào)錯(cuò)時(shí),第一條的teacherMapper.updateTeacher(teacher)也被直接判定為false,這個(gè)方法中的內(nèi)容都不會(huì)被執(zhí)行到
只有當(dāng)這個(gè)方法正常被執(zhí)行后,才可能被執(zhí)行
所以這就是@Transactional事務(wù)管理的作用