springBoot事务

SpringBoot事务回滚

springBoot自动实现事务回滚

springBoot事务管理代码实现:

主启动类:注解@EnableTransactionManagement,开启事务管理

image-20220715155758466

application.yaml配置文件:mysql 8.x 配置信息

spring:
  datasource: # mysql数据库连接
    type: com.zaxxer.hikari.HikariDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8&characterEncoding=utf-8
    username: root
    password: root

初始表数据:

image-20220715160221624

image-20220715160257683

业务类:

UserService类:

    //@Transactional 先注释
    public R saveUser(User user) {
        //新增用户信息
        userMapper.insert(user);

        //代码异常
        int i = 1 / 0;

        UserDetail userDetail = new UserDetail();
        userDetail.setUserId(user.getId());
        userDetail.setQq(String.valueOf(System.currentTimeMillis()).substring(0, 10));
        //新增用户详情信息
        userDetailMapper.insert(userDetail);

        user.setUserDetail(userDetail);
        return R.ok().data("user", user);
    }

测试类:

@SpringBootTest
class SpringApplyApplicationTests {

    @Autowired
    private UserService userService;

    @Test
    void contextLoads() {
        User user = new User();
        user.setUser("likelong");
        user.setBalance(10000);

        userService.saveUser(user);
    }

}

测试结果:

image-20220715160905158数据库只有用户信息表有数据,用户详情表没有数据,这是有问题的

user_table表

image-20220715161013837

user_detail表

image-20220715161113946

删除用户表中数据,解除注解@Transactional注释,重新测试。

此时没有任何问题,两张表中都没有任何数据。这是因为项目业务代码抛出异常,被springBoot捕获到,springBoot帮我们进行了数据库的回滚操作。

如果我们不抛出异常而是进行异常捕获会发生什么呢。修改UserService业务代码如下:

@Service
@Slf4j
public class UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private UserDetailMapper userDetailMapper;

    @Transactional
    public R saveUser(User user) {
        //捕获异常
        try {
            userMapper.insert(user);

            //代码异常
            int i = 1 / 0;

            UserDetail userDetail = new UserDetail();
            userDetail.setUserId(user.getId());
            userDetail.setQq(String.valueOf(System.currentTimeMillis()).substring(0, 10));
            userDetailMapper.insert(userDetail);
           
            user.setUserDetail(userDetail);
            return R.ok().data("user", user);
        } catch (Exception e) {
            log.error("新增用户出现异常~");
            e.printStackTrace();
        }

        return null;
    }
}

再次测试:事务回滚失效,会有上述相同的问题 – 数据库只有用户信息表有数据,用户详情表没有数据。

springBoot手动触发事务回滚

再次删除库中数据,修改代码测试:

TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();手动触发事务回滚

@Service
@Slf4j
public class UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private UserDetailMapper userDetailMapper;

    @Transactional
    public R saveUser(User user) {
        try {
            userMapper.insert(user);

            //代码异常
            int i = 1 / 0;

            UserDetail userDetail = new UserDetail();
            userDetail.setUserId(user.getId());
            userDetail.setQq(String.valueOf(System.currentTimeMillis()).substring(0, 10));
            userDetailMapper.insert(userDetail);

            user.setUserDetail(userDetail);
            return R.ok().data("user", user);
        } catch (Exception e) {
            log.error("新增用户出现异常~");

            //手动触发事务回滚
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            e.printStackTrace();
        }

        return null;
    }
}

手动触发事务回滚,数据正常,两个表格都没有数据。一切正常。

注意事项:

  1. 抛出的异常不要catch ,否则相当于没有异常。导致无法自动回滚。
  2. 如果通过抛出异常的方法来回滚。方法中的后续代码就不会再执行。如果用TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); 手动触发回滚,则方法中的后续代码还会执行。

总结:

想要让springBoot帮助我们实现数据库事务回滚,我们业务代码尽量不要catch我们的异常,要是真的需要捕获或者是没有异常发生,需要事务回滚,可以手动触发事务回滚TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()【方法上的 @Transactional依旧不能少】。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不进大厂不改名二号

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值