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