Spring事务管理(数据一致性)

Spring事务管理(数据一致性)
1. 基础/核心1.1、Spring 支持哪两种事务管理方式编程式事务、声明式事务编程式事务使用TransactionTemplate或PlatformTransactionManager手动编写代码控制事务的提交与回滚。灵活度高但代码侵入性强。声明式事务基于AOP面向切面编程通过Transactional注解或 XML 配置将事务管理与业务代码分离。代码无侵入最常用。1.2、Transactional注解有哪些常用的属性propagation事务传播行为默认REQUIRED。isolation事务隔离级别默认DEFAULT。timeout事务超时时间单位秒。readOnly只读事务。优化只读操作的性能限制事务内的写操作。rollbackFor指定哪些异常触发回滚Spring 默认仅在遇到RuntimeException和Error时回滚。noRollbackFor指定哪些异常不触发回滚。2. 高频/进阶2.1、【必考】Spring 事务的传播行为Propagation有哪些Spring 共定义了 7 种传播行为用于解决业务方法互相调用时事务如何流转的问题REQUIRED默认如果当前存在事务则加入该事务如果不存在则创建一个新事务。外层与内层方法共用同一个事务任何地方报错全盘回滚。REQUIRES_NEW创建一个新事务。如果当前存在事务则将当前事务挂起。内层新事务的提交或回滚独立于外层事务互不影响。NESTED如果当前存在事务则在嵌套事务内执行利用数据库的Savepoint 保存点。内层事务回滚会跳回保存点不影响外层事务提交但外层事务回滚内层嵌套事务会随之回滚。其他 4 种SUPPORTS有则用无则无、NOT_SUPPORTED以非事务运行有则挂起、MANDATORY必须在事务中运行否则报错、NEVER不能在事务中运行否则报错。2.2、Spring 事务的隔离级别有哪些它们和数据库的隔离级别有什么关系Spring 的Isolation枚举定义了 5 个隔离级别DEFAULT使用底层数据库默认的隔离级别MySQL 默认为RROracle 默认为RC。READ_UNCOMMITTED读未提交引发脏读、不可重复读、幻读。READ_COMMITTED读已提交解决脏读引发不可重复读、幻读。REPEATABLE_READ可重复读解决脏读、不可重复读引发幻读。SERIALIZABLE串行化解决所有并发问题性能最低。关系Spring 事务隔离级别是对底层数据库能力的封装。如果数据库如底层未开启某隔离级别不支持Spring 配置的隔离级别将无法生效。3. 源码/深度3.1、【必考】Spring 事务在什么情况下会失效内部方法自调用在同一个类中A 方法无事务通过this.B()调用本类带Transactional的 B 方法此时调用不走代理对象事务失效。修饰非public方法Spring 默认要求Transactional只能应用在public方法上。修饰private、protected或package-private方法时AOP 代理会直接忽略。异常被内部try-catch吞掉业务代码自行捕获了异常却没有重新抛出或者抛出了非RuntimeException且未配置rollbackFor Exception.class导致 Spring 无法感知异常事务正常提交。数据库引擎本身不支持事务如 MySQL 使用了MyISAM存储引擎而非InnoDB。目标类未被 Spring 管理类上漏掉了Service或Component注解该类不会生成 Spring Bean 及其代理对象。3.2、Spring 事务的底层原理是什么它是如何利用 AOP 和ThreadLocal实现的AOP 拦截Spring 在初始化 Bean 时若发现方法上有Transactional会通过 JDK 动态代理或 CGLIB 动生成代理对象。调用该方法时会被TransactionInterceptor拦截。连接绑定与 ThreadLocal拦截器通过PlatformTransactionManager获取数据库连接。为了确保在同一个事务周期内例如 Service 调多个 DAO所有数据库操作都使用同一个数据库连接Spring 利用TransactionSynchronizationManager内部的ThreadLocalMapObject, Object将当前数据库连接Connection与当前线程进行绑定。增强逻辑代理对象在目标业务方法执行前开启事务autoCommit false执行业务方法各个 DAO 从ThreadLocal拿同一个连接执行 SQL若成功则提交commit若抛出指定异常则回滚rollback最后将连接从ThreadLocal中清除并关闭。