SpringBoot整合事务Transactional

一、启动事务

1、启动类添加

@EnableTransactionManagement

2、方法或者类添加

@Transactional
    如果在方法添加该注解则该方法开启事务 如果在类添加该注解则该类所有方法开启事务

二、测试

1、准备两张表分别为图书表和用户表

2、如果不添加事务,测试以下代码

package com.redis.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.redis.domain.Book;
import com.redis.domain.User;
import com.redis.mapper.UserMapper;
import com.redis.service.BookService;
import com.redis.mapper.BookMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
* @author 11604
* @description 针对表【book】的数据库操作Service实现
* @createDate 2023-04-01 09:15:30
*/
@Service
public class BookServiceImpl extends ServiceImpl<BookMapper, Book>
    implements BookService{
    @Autowired
    private BookMapper bookMapper;
    @Autowired
    private UserMapper userMapper;

//    @Transactional
    @Override
    public void buyBook(Long bookId, Long userId) {

        //更新图书库存
        Long price = changeBookStock(bookId);

        //手动异常
        int i=1/0;

        //更新用户余额
        changeUserAccount(userId, price);

    }

    private void changeUserAccount(Long userId, Long price) {
        User user = userMapper.selectById(userId);
        Long account = user.getAccount();
        user.setAccount(account- price);
        System.out.println(user);
        userMapper.updateById(user);
    }

    private Long changeBookStock(Long bookId) {
        Book book = bookMapper.selectById(bookId);
        book.setStock(book.getStock()-1);
        Long price = book.getPrice();
        System.out.println(book);
        bookMapper.updateById(book);
        return price;
    }
}

测试结果为:

出现了只买书不扣钱的情况

2、添加事务注解以后:

package com.redis.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.redis.domain.Book;
import com.redis.domain.User;
import com.redis.mapper.UserMapper;
import com.redis.service.BookService;
import com.redis.mapper.BookMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
* @author 11604
* @description 针对表【book】的数据库操作Service实现
* @createDate 2023-04-01 09:15:30
*/
@Service
public class BookServiceImpl extends ServiceImpl<BookMapper, Book>
    implements BookService{
    @Autowired
    private BookMapper bookMapper;
    @Autowired
    private UserMapper userMapper;

    @Transactional
    @Override
    public void buyBook(Long bookId, Long userId) {

        //更新图书库存
        Long price = changeBookStock(bookId);

        //手动异常
        int i=1/0;

        //更新用户余额
        changeUserAccount(userId, price);

    }

    private void changeUserAccount(Long userId, Long price) {
        User user = userMapper.selectById(userId);
        Long account = user.getAccount();
        user.setAccount(account- price);
        System.out.println(user);
        userMapper.updateById(user);
    }

    private Long changeBookStock(Long bookId) {
        Book book = bookMapper.selectById(bookId);
        book.setStock(book.getStock()-1);
        Long price = book.getPrice();
        System.out.println(book);
        bookMapper.updateById(book);
        return price;
    }
}

测试结果为:

如果出现异常就会事务回滚

三、@Transactional常用配置

经验分享 程序员 微信小程序 职场和发展