Spring 事务管理是 Spring 框架核心特性之一,通过配置隔离级别和传播属性,解决并发场景下的数据一致性问题,规范事务执行行为。
一、Spring 事务隔离级别
用于解决并发访问的脏读、不可重复读、幻读问题,共5种,default为默认,其余与JDBC一一对应。
- default(默认隔离级别)
-
PlatformTransactionManager 默认隔离级别
-
沿用数据库默认事务隔离级别(如MySQL默认可重复读、Oracle默认读已提交)
- read_uncommitted(读未提交)
-
一个事务可读取另一个事务未提交的数据
-
问题:存在脏读、不可重复读、幻读,一致性最弱
- read_committed(读已提交)
-
仅能读取另一个事务已提交的数据,无法读取未提交数据
-
优势:避免脏读;问题:无法避免不可重复读、幻读
- repeatable_read(可重复读)
-
多次读取同一批数据结果一致,仅读取其他事务已提交数据
-
优势:避免脏读、不可重复读;问题:无法避免幻读
- serializable(串行化)
-
最高隔离级别,所有事务顺序串行执行
-
优势:避免脏读、不可重复读、幻读,一致性最强;问题:并发性能低、执行成本高
二、Spring 事务传播属性
定义多事务方法相互调用时,事务的创建、继承、挂起规则,共7种,required为默认。
- required(默认传播属性)
-
存在事务则支持当前事务;无事务则新建事务
-
为每个被调用方法创建逻辑事务域,嵌套调用时继承前序事务
-
实例:用户下单(order())方法调用扣减库存(deductStock())和扣减余额(deductBalance())方法,三者均配置required。调用order()时会新建事务,deductStock()和deductBalance()加入该事务,任意一个方法失败,整个事务回滚(库存和余额均不改变)。
- mandatory
-
存在事务则支持;无事务则抛出异常(必须在事务中执行)
-
实例:核心业务方法submitOrder()(提交订单)配置mandatory,必须被有事务的方法调用。若直接调用submitOrder()(无事务),则抛出异常;若被有事务的order()方法调用,则加入order()的事务,一同提交或回滚。
- never
-
以非事务方式执行;存在事务则抛出异常(禁止事务中执行)
-
实例:日志记录方法logOperation()配置never,用于记录操作日志(无需事务)。若在有事务的order()方法中调用logOperation(),则抛出异常;直接调用logOperation(),正常记录日志,即使失败也不影响其他操作。
- supports
-
存在事务则支持;无事务则以非事务方式执行(可有可无)
-
实例:查询商品库存方法queryStock()配置supports。若在有事务的deductStock()方法中调用,就加入该事务;若用户直接查询库存(无事务),则以非事务方式执行,查询结果不受事务影响。
- not_supports
-
以非事务方式执行;存在事务则挂起当前事务,执行后恢复
-
实例:发送通知方法sendNotice()配置not_supports,用于给用户发送下单通知(无需事务)。若在有事务的order()方法中调用,会先挂起order()的事务,发送通知完成后,再恢复order()的事务继续执行,即使通知发送失败,也不影响order()事务的提交/回滚。
- required_new
-
始终新建独立事务;存在事务则挂起原事务,新事务与原事务独立
-
实例:订单支付方法payOrder()配置required_new,被有事务的order()方法调用。调用payOrder()时会挂起order()的事务,新建独立事务执行支付;若支付失败,仅回滚payOrder()的事务(支付记录回滚),order()的事务可继续执行(比如记录订单状态为支付失败)。
- nested(嵌套事务)
-
基于当前事务创建嵌套事务,添加保存点,与外层事务同步提交/回滚
-
核心:内层失败仅回滚自身,不影响外层;外层回滚则连带内层回滚
-
实例:order()方法(外层事务)调用addOrderLog()方法(内层,配置nested)。若addOrderLog()执行失败(比如日志插入异常),仅回滚addOrderLog()的操作(日志不插入),order()的事务可正常提交(订单正常创建);若order()方法失败回滚,addOrderLog()的操作也会随之回滚。

本文详细介绍了Spring框架中的事务管理机制,包括事务的隔离级别如默认、读未提交、读已提交、可重复读及串行化;同时阐述了事务的传播特性如required、mandatory、never、supports、not_supports、required_new及nested等。

1247

被折叠的 条评论
为什么被折叠?



