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;
}
}