2021-09-05 10:11:02
Spring事务传播机制和隔离级别是控制事务传递与隔离的核心机制,分别决定了事务方法调用时的边界规则和并发事务间的数据可见性。
一、Spring事务传播机制Spring定义了7种传播行为,用于控制事务方法调用时的边界与执行方式:

REQUIRED(默认)若当前存在事务,则加入该事务;若无事务,则创建新事务。适用于核心业务方法。
SUPPORTS若当前存在事务,则加入;若无事务,则以非事务方式执行。适用于日志记录等辅助操作。
MANDATORY必须存在事务,否则抛出异常。适用于强制依赖事务的场景。
REQUIRES_NEW无论当前是否存在事务,均创建新事务。若存在事务,则挂起原事务。适用于需要独立事务的操作(如主事务失败后仍需执行的清理逻辑)。
NOT_SUPPORTED以非事务方式执行,若存在事务则挂起。适用于无需事务的场景(如批量数据导出)。
NEVER以非事务方式执行,若存在事务则抛出异常。适用于明确禁止事务的场景。
NESTED若当前存在事务,则创建嵌套事务(保存点);若无事务,则创建新事务。适用于部分回滚的场景(如大事务中某子操作失败但不希望整体回滚)。
选择建议:
隔离级别定义了并发事务间的数据可见性规则,防止脏读、不可重复读和幻读:

DEFAULT使用数据库默认隔离级别(如MySQL默认REPEATABLE_READ,Oracle默认READ_COMMITTED)。
READ_UNCOMMITTED允许读取未提交数据,并发性能最高,但可能发生脏读。适用于对数据一致性要求极低的场景。
READ_COMMITTED只能读取已提交数据,防止脏读,但可能发生不可重复读。适用于大多数业务场景(如电商订单查询)。
REPEATABLE_READ同一事务内多次读取同一数据结果一致,防止脏读和不可重复读,但可能发生幻读。适用于需要数据强一致的场景(如库存扣减)。
SERIALIZABLE事务串行执行,完全隔离,但并发性能最低。适用于对数据一致性要求极高的场景(如金融交易)。
选择建议:
通过@Transactional注解配置传播机制和隔离级别:
import org.springframework.transaction.annotation.Transactional;@Servicepublic class OrderService { @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED) public void createOrder() { // 业务逻辑 } @Transactional(propagation = Propagation.REQUIRES_NEW) public void updateInventory() { // 独立事务逻辑 }}配置说明:
通过XML配置事务属性:
<tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="createOrder" propagation="REQUIRED" isolation="READ_COMMITTED"/> <tx:method name="updateInventory" propagation="REQUIRES_NEW"/> </tx:attributes></tx:advice><aop:config> <aop:pointcut id="servicePointcut" expression="execution(* com.example.service.*.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="servicePointcut"/></aop:config>适用场景:
通过TransactionTemplate或PlatformTransactionManager手动控制事务边界:
import org.springframework.transaction.support.TransactionTemplate;@Servicepublic class PaymentService { @Autowired private TransactionTemplate transactionTemplate; public void processPayment() { transactionTemplate.execute(status -> { try { // 业务逻辑 return true; } catch (Exception e) { status.setRollbackOnly(); return false; } }); }}适用场景:
自调用问题:方法内部调用另一个@Transactional方法时,事务不生效。原因:Spring通过代理实现事务,自调用绕过代理。解决方案:通过注入的Bean调用方法(如this.anotherMethod()改为bean.anotherMethod())。
异常处理不当:默认仅对RuntimeException回滚,Checked Exception不会触发回滚。解决方案:通过@Transactional(rollbackFor = Exception.class)指定回滚异常类型。
方法非public:Spring AOP仅代理public方法。解决方案:将方法改为public。
避免长事务:长事务占用数据库连接,降低并发性能。解决方案:拆分大事务为多个小事务。
合理选择隔离级别:高隔离级别(如SERIALIZABLE)会降低并发性能。解决方案:根据业务需求选择最低满足要求的隔离级别(如READ_COMMITTED)。
核心业务方法:REQUIRED + READ_COMMITTED(平衡一致性与性能)。
独立操作:REQUIRES_NEW + READ_COMMITTED(确保操作独立性)。
严格一致性场景:REQUIRED + REPEATABLE_READ(防止不可重复读)。

通过合理配置传播机制和隔离级别,可以确保事务的ACID特性(原子性、一致性、隔离性、持久性),同时优化系统性能。