背景:面试被问到一个提,说说事务失效的场景,答的很不好,所以平时还是加强总结,发散思维,多做准备。
失效可能的原因
Spring 事务失效的8大原因
1、数据库引擎是否支持事务(Myisam不支持事务)
2、注解所在的类是否被加载成Bean(对象没有被Spring管理)
3、注解所在的方法是否为public修饰
4、是否发生了自身调用问题
5、所有数据源是否加载了事务管理器
6、@transaction的propagation配置是否正确
7、捕获了异常
8、checked exceptions无效,需要配置rollbackFor = Throwable.class
9、只读事务 只在
ps:交简单的说明了几种场景
ps通俗易懂
java中异常的分类(事务只回滚unchecked异常)
java里面将派生于Error或者RuntimeException(比如空指针,1/0)的异常称为unchecked异常,
其他继承自java.lang.Exception得异常统称为Checked Exception,如IOException、TimeoutException等
ps:
public class RuntimeException extends Exception public class Exception extends Throwable
Exception中非RuntimeException的异常为checked 异常,编译会无法通过
+-----------+ | Throwable | +-----------+ / / +-------+ +-----------+ | Error | | Exception | +-------+ +-----------+ / | / | \________/ \______/ +------------------+ unchecked checked | RuntimeException | +------------------+ / | | \_________________/ unchecked
辣么再通俗一点:你写代码出现的空指针等异常,会被回滚,文件读写,网络出问题,spring就没法回滚了。然后我教大家怎么记这个,因为很多同学容易弄混,你写代码的时候有些IOException我们的编译器是能够检测到的,说以叫checked异常,你写代码的时候空指针等死检测不到的,所以叫unchecked异常。这样是不是好记一些啦
事务的传播机制理解
ps:着重介绍了下面两个传播级别,结合例子很通俗易懂
PROPAGATION_REQUIRED
PROPAGATION_REQUIRES_NEW
案例二 PROPAGATION_REQUIRED
@Transactional @Override public void Example2(User user) { userMapper.insert(user); try { propagationService.required(); } catch (Exception e) { e.printStackTrace(); } } // 另一个service @Transactional @Override public void required() { throw new NullPointerException("肥朝假装抛出了异常"); }
异常捕获,是否会插入数据呢?
这个到底会不会插入数据呢?毕竟这个异常被try起来了。这个时候,正常的思维都会认为,能正常插入数据,但是答案是,不会插入数据,并且抛出异常
org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only
ps:这里是因为A B共用一个事务,A中的事务,在B抛出异常时候,被标记为回滚。最好看原文
案例二 PROPAGATION_REQUIRES_NEW
@Transactional @Override public void Example3(User user) { userMapper.insert(user); try { propagationService.requiresNew(); } catch (Exception e) { e.printStackTrace(); } } @Transactional(propagation = Propagation.REQUIRES_NEW) @Override public void requiresNew() { throw new NullPointerException("肥朝假装抛出了异常"); }
答案是能插入数据
事务传入机制的源码实现
未完待续