0 课程地址
https://www.imooc.com/video/16731
1 课程重点
1.1 常见应用
REQUIRED:当一个操作需要执行的时候,有事务会把操作加到事务中去,没有事务会另起一个新的事务,然后再去执行。适用于 增删改操作,执行错误会回滚。
SUPPORTS:有事务会用当前事务加入进去执行,无事务直接脱离事务执行,适用于 读取操作。
@Transactional(propagation=Propagation.SUPPORTS)查询
@Transactional(propagation=Propagation.REQUIRED)增加,删除,修改
1.2 Spring注解和Springboot注解对应关系
1.3 事务隔离级别
DEFAULT READ_UNCOMMITTED
READ_COMMITTED REPEATABLE_READ SERIALIZABLE
1.4 事务传播行为
REQUIRED SUPPORTS MANDATORY
REQUIRES_NEW NOT_SUPPORTED NEVER NESTED
2 demo相关
2.1 不加入Required注解,不进行回滚反例(主要见标红部分)
MyBatisCRUDController
package com.example.demo.controller; /** * MyBatisCRUDController * * @author 魏豆豆 * @date 2020/12/20 */ import com.example.demo.pojo.SysUser; import com.example.demo.service.UserService; import com.example.demo.tools.JSONResult; import org.n3r.idworker.Sid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.Date; import java.util.List; @RestController @RequestMapping("mybatis") public class MyBatisCRUDController { @Autowired private UserService userService; @Autowired private Sid sid; @RequestMapping("/saveUser") public JSONResult saveUser() throws Exception { String userId = sid.nextShort(); SysUser user = new SysUser(); user.setId(userId); user.setUsername("imooc" + new Date()); user.setNickname("imooc" + new Date()); user.setPassword("abc123"); user.setIsDelete(0); user.setRegistTime(new Date()); userService.saveUser(user); return JSONResult.ok("保存成功"); } @RequestMapping("/updateUser") public JSONResult updateUser() { SysUser user = new SysUser(); user.setId("10011001"); user.setUsername("10011001-updated" + new Date()); user.setNickname("10011001-updated" + new Date()); user.setPassword("10011001-updated"); user.setIsDelete(0); user.setRegistTime(new Date()); userService.updateUser(user); return JSONResult.ok("保存成功"); } @RequestMapping("/deleteUser") public JSONResult deleteUser(String userId) { userService.deleteUser(userId); return JSONResult.ok("删除成功"); } @RequestMapping("/queryUserById") public JSONResult queryUserById(String userId) { return JSONResult.ok(userService.queryUserById(userId)); } @RequestMapping("/queryUserList") public JSONResult queryUserList() { SysUser user = new SysUser(); user.setUsername("imooc"); user.setNickname("lee"); List<SysUser> userList = userService.queryUserList(user); return JSONResult.ok(userList); } @RequestMapping("/queryUserListPaged") public JSONResult queryUserListPaged(Integer page) { if (page == null) { page = 1; } int pageSize = 10; SysUser user = new SysUser(); // user.setNickname("lee"); List<SysUser> userList = userService.queryUserListPaged(user, page, pageSize); return JSONResult.ok(userList); } @RequestMapping("/queryUserByIdCustom3") public JSONResult queryUserByIdCustom2(String userId) { return JSONResult.ok(userService.queryUserByIdCustom(userId)); } /** * 自定义mapper * @return */ @RequestMapping("/queryUserByCusMapper") public JSONResult queryUserByCusMapper(String userId){ return JSONResult.ok(userService.queryUserByCusMapper(userId)); } @RequestMapping("/saveUserTransactional") public JSONResult saveUserTransactional() { String userId = sid.nextShort(); SysUser user = new SysUser(); user.setId(userId); user.setUsername("lee" + new Date()); user.setNickname("lee" + new Date()); user.setPassword("abc123"); user.setIsDelete(0); user.setRegistTime(new Date()); userService.saveUserTransactional(user); return JSONResult.ok("保存成功"); } }
UserService
package com.example.demo.service; /** * UserService * * @author 魏豆豆 * @date 2020/12/20 */ import com.example.demo.pojo.SysUser; import java.util.List; public interface UserService { public void saveUser(SysUser user) throws Exception; public void updateUser(SysUser user); public void deleteUser(String userId); public SysUser queryUserById(String userId); public List<SysUser> queryUserList(SysUser user); public List<SysUser> queryUserListPaged(SysUser user, Integer page, Integer pageSize); public SysUser queryUserByIdCustom(String userId); public SysUser queryUserByCusMapper(String userId); public void saveUserTransactional(SysUser user); }
UserServiceImpl
package com.example.demo.service.impl; /** * UserServiceImpl * * @author 魏豆豆 * @date 2020/12/20 */ import java.util.List; import com.example.demo.mapper.SysUserMapper; import com.example.demo.mapper.SysUserMapperCus; import com.example.demo.mapper.SysUserMapperCustom; import com.example.demo.pojo.SysUser; import com.example.demo.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import org.thymeleaf.util.StringUtils; import com.github.pagehelper.PageHelper; import tk.mybatis.mapper.entity.Example; @Service public class UserServiceImpl implements UserService { @Autowired private SysUserMapper userMapper; @Autowired private SysUserMapperCustom userMapperCustom; @Autowired private SysUserMapperCus sysUserMapperCus; @Override @Transactional(propagation = Propagation.REQUIRED) public void saveUser(SysUser user) throws Exception { try { Thread.sleep(4000); } catch (InterruptedException e) { e.printStackTrace(); } //mybaties jar包中的方法 userMapper.insert(user); } @Override @Transactional(propagation = Propagation.REQUIRED) public void updateUser(SysUser user) { userMapper.updateByPrimaryKeySelective(user); // userMapper.updateByPrimaryKey(user); } @Override @Transactional(propagation = Propagation.REQUIRED) public void deleteUser(String userId) { userMapper.deleteByPrimaryKey(userId); } @Override @Transactional(propagation = Propagation.SUPPORTS) public SysUser queryUserById(String userId) { try { Thread.sleep(6000); } catch (InterruptedException e) { e.printStackTrace(); } return userMapper.selectByPrimaryKey(userId); } @Override @Transactional(propagation = Propagation.SUPPORTS) public List<SysUser> queryUserList(SysUser user) { try { Thread.sleep(11000); } catch (InterruptedException e) { e.printStackTrace(); } Example example = new Example(SysUser.class); Example.Criteria criteria = example.createCriteria(); if (!StringUtils.isEmptyOrWhitespace(user.getUsername())) { // criteria.andEqualTo("username", user.getUsername()); criteria.andLike("username", "%" + user.getUsername() + "%"); } if (!StringUtils.isEmptyOrWhitespace(user.getNickname())) { criteria.andLike("nickname", "%" + user.getNickname() + "%"); } List<SysUser> userList = userMapper.selectByExample(example); return userList; } @Override @Transactional(propagation = Propagation.SUPPORTS) public List<SysUser> queryUserListPaged(SysUser user, Integer page, Integer pageSize) { // 开始分页 PageHelper.startPage(page, pageSize); Example example = new Example(SysUser.class); Example.Criteria criteria = example.createCriteria(); if (!StringUtils.isEmptyOrWhitespace(user.getNickname())) { criteria.andLike("nickname", "%" + user.getNickname() + "%"); } example.orderBy("registTime").desc(); List<SysUser> userList = userMapper.selectByExample(example); return userList; } @Override @Transactional(propagation = Propagation.SUPPORTS) public SysUser queryUserByIdCustom(String userId) { List<SysUser> userList = userMapperCustom.queryUserSimplyInfoById(userId); if (userList != null && !userList.isEmpty()) { return (SysUser)userList.get(0); } return null; } @Override @Transactional(propagation = Propagation.SUPPORTS) public SysUser queryUserByCusMapper(String userId) { List<SysUser> userList = sysUserMapperCus.queryUserMapperCus(userId); if (userList != null && !userList.isEmpty()) { return (SysUser)userList.get(0); } return null; } @Override public void saveUserTransactional(SysUser user) { //正常情况下,下边异常,这里应该不插上值,进行回滚。但是实际上不是(详情见下方测试数据库查询截图) userMapper.insert(user); int a = 1 / 0; user.setIsDelete(1); userMapper.updateByPrimaryKeySelective(user); } }
测试结果:
2.2 加入Required注解,进行回滚正例
MyBatisCRUDController(同上)
UserService(同上)
UserServiceImpl
package com.example.demo.service.impl; /** * UserServiceImpl * * @author 魏豆豆 * @date 2020/12/20 */ import java.util.List; import com.example.demo.mapper.SysUserMapper; import com.example.demo.mapper.SysUserMapperCus; import com.example.demo.mapper.SysUserMapperCustom; import com.example.demo.pojo.SysUser; import com.example.demo.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import org.thymeleaf.util.StringUtils; import com.github.pagehelper.PageHelper; import tk.mybatis.mapper.entity.Example; @Service public class UserServiceImpl implements UserService { @Autowired private SysUserMapper userMapper; @Autowired private SysUserMapperCustom userMapperCustom; @Autowired private SysUserMapperCus sysUserMapperCus; @Override @Transactional(propagation = Propagation.REQUIRED) public void saveUser(SysUser user) throws Exception { try { Thread.sleep(4000); } catch (InterruptedException e) { e.printStackTrace(); } //mybaties jar包中的方法 userMapper.insert(user); } @Override @Transactional(propagation = Propagation.REQUIRED) public void updateUser(SysUser user) { userMapper.updateByPrimaryKeySelective(user); // userMapper.updateByPrimaryKey(user); } @Override @Transactional(propagation = Propagation.REQUIRED) public void deleteUser(String userId) { userMapper.deleteByPrimaryKey(userId); } @Override @Transactional(propagation = Propagation.SUPPORTS) public SysUser queryUserById(String userId) { try { Thread.sleep(6000); } catch (InterruptedException e) { e.printStackTrace(); } return userMapper.selectByPrimaryKey(userId); } @Override @Transactional(propagation = Propagation.SUPPORTS) public List<SysUser> queryUserList(SysUser user) { try { Thread.sleep(11000); } catch (InterruptedException e) { e.printStackTrace(); } Example example = new Example(SysUser.class); Example.Criteria criteria = example.createCriteria(); if (!StringUtils.isEmptyOrWhitespace(user.getUsername())) { // criteria.andEqualTo("username", user.getUsername()); criteria.andLike("username", "%" + user.getUsername() + "%"); } if (!StringUtils.isEmptyOrWhitespace(user.getNickname())) { criteria.andLike("nickname", "%" + user.getNickname() + "%"); } List<SysUser> userList = userMapper.selectByExample(example); return userList; } @Override @Transactional(propagation = Propagation.SUPPORTS) public List<SysUser> queryUserListPaged(SysUser user, Integer page, Integer pageSize) { // 开始分页 PageHelper.startPage(page, pageSize); Example example = new Example(SysUser.class); Example.Criteria criteria = example.createCriteria(); if (!StringUtils.isEmptyOrWhitespace(user.getNickname())) { criteria.andLike("nickname", "%" + user.getNickname() + "%"); } example.orderBy("registTime").desc(); List<SysUser> userList = userMapper.selectByExample(example); return userList; } @Override @Transactional(propagation = Propagation.SUPPORTS) public SysUser queryUserByIdCustom(String userId) { List<SysUser> userList = userMapperCustom.queryUserSimplyInfoById(userId); if (userList != null && !userList.isEmpty()) { return (SysUser)userList.get(0); } return null; } @Override @Transactional(propagation = Propagation.SUPPORTS) public SysUser queryUserByCusMapper(String userId) { List<SysUser> userList = sysUserMapperCus.queryUserMapperCus(userId); if (userList != null && !userList.isEmpty()) { return (SysUser)userList.get(0); } return null; } @Override
@Transactional(propagation = Propagation.REQUIRED) public void saveUserTransactional(SysUser user) { //事务回滚,没有插上值截图的值,(还是上一次插上的值,没有新增条数