Spring 事務rollback-only問題


package xyz.pascall.mybatis.spring.boot.learn.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import xyz.pascall.mybatis.spring.boot.learn.entity.User;
import xyz.pascall.mybatis.spring.boot.learn.mapper.UserMapper;
import xyz.pascall.mybatis.spring.boot.learn.service.PersonService;
import xyz.pascall.mybatis.spring.boot.learn.service.UserService;

/**
 * UserServiceImpl
 * <p>
 * Spring事務rollback-only原因: org.springframework.transaction.UnexpectedRollbackException:
 *      Transaction rolled back because it has been marked as rollback-only
 *
 *  兩個事務(rollback-only):(兩個事務都會回滾)(本意:第一個事務不回滾)
 *      userService.addInfo(name)(事務1)(rollback-only)中try-catch personService.addPerson(user)(事務2)(異常)
 *      userService.addInfo(name)(事務1)try-catch userService.create(user)(依賴注入)(事務2)(異常)
 *
 *  一個事務:(兩個方法都不會回滾)
 *      userService.addInfo(name)(事務1)try-catch create(user)(事務1)(異常)
 *      分析:其實只有一個最外層的事務,由於異常已被try-catch所以事務不會回滾,也沒有rollback-only
 *
 *
 *  解決rollback-only問題:
 *      1.在第二個事務上加:(第一個不回滾,第二個回滾)
 *          @Transactional(propagation = Propagation.REQUIRES_NEW)
 *      2.在service層方法的catch語句中:(兩個事務都回滾)
 *          TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
 *      3.在service層方法的catch語句中:(兩個事務都回滾)
 *          throw new RuntimeException(e.getMessage());
 * @author Jie Zhang, 2019/7/31
 * @version DEMO v1.0
 */
@Service
@Slf4j
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired private UserService userService;

    @Autowired
    private PersonService personService;

    @Override
    public User getUser(Integer id) {
        return userMapper.getUser(id);
    }

    @Override
    public PageInfo<User> query(Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum == null ? 1 : pageNum,
                pageSize == null ? 5 : pageSize, true);
        return new PageInfo<>(userMapper.query());
    }


    @Transactional
    @Override
    public void addInfo(final String name) {
        User user = new User().setName(name).setAge(30).setEmail(name + "@qq.com");
        log.info(String.valueOf(userMapper.add(user)));
        try {
            userService.create(user);
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            log.error("不斷程序,用來輸出日志~ " + e.getMessage());
            // throw new RuntimeException(e.getMessage());
        }
    }

    @Transactional
    @Override
    public int create(User user) {
        user.setName("pascall-pascall");
        user.setEmail("pascall-pascall@qq.com");
        log.info(String.valueOf(userMapper.add(user)));
        int i = 1 / 0;
        return i;
    }

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM