springboot中的事务
使用:
@EnableTransactionManagement 为总开关,总闸
@Transactional 具体的函数开关,具体的灯
------------------------------------------------------------------------------------------------------------------------
失效的情况:
1. 最常见的,方法内部调用, 例如:
@Service
public class UserServiceImpl implements UserService {
    @Autowired
private UserMapper userMapper;
    // 外部调用这个方法,它没有 @Transactional 注解
public void createUserWrong(User user) {
// ... 一些其他逻辑 ...
insertUser(user); // <--- 问题所在!这是内部调用
}
    @Transactional
public void insertUser(User user) {
userMapper.insert(user);
}
}
为啥:
Spring 的事务是通过 AOP 代理实现的。当一个 Bean 被 Spring 容器管理时,Spring 会为它创建一个代理对象。外部对该 Bean 方法的调用,实际上是先调用代理对象,代理对象在调用实际方法前开启事务。而如果你在一个 Bean 的内部,通过 this 关键字来调用它自己的另一个方法,这个调用会直接指向原始对象,从而绕过了代理对象,事务自然就失效了。
2. 方法访问权限不够,例如:
@Service
public class OrderService {
    @Transactional
private void createOrderInternal(Order order) { // <--- private 方法,事务失效
// ... 数据库操作 ...
}
}
为啥:
Spring AOP 代理默认只能拦截 public 方法。
3.异常类型没有捕捉对,例如:
@Transactional(rollbackFor = MyBusinessException.class)
public void updateStock(Long productId) throws Exception { productMapper.decreaseStock(productId);
throw new BizException("一个自定义的业务异常");
}
小插曲,如果裸一个@Transactional,哪些情况下会回滚(非受检异常):
RuntimeException (运行时异常) 及其所有子类。
Error (错误) 及其所有子类。
常见举例:
NullPointerException: 对一个 null 对象进行操作。
IllegalArgumentException: 传入了一个不合法的参数。
IndexOutOfBoundsException: 数组或列表越界。
IllegalStateException: 对象处于一个不正确的状态。
ClassCastException: 类型转换异常。
ArithmeticException: 数学计算异常,如除以零。
OutOfMemoryError: 内存溢出错误。
StackOverflowError: 栈溢出错误。
4. 数据库引擎不支持事务,这个不多说,项目技术选型的时候就知道了。
