当前位置: 首页 > news >正文

Spring (十)事务

目录

一 Spring数据库的相关配置:

1 导入包:

2 配置数据库连接信息

3 可以直接使用:DataSource,JdbcTemplate

二 事务管理:

1 事务管理的实现

1.1 开启Spring事务管理

1.2 为指定方法添加事务

2 关键类与接口

2.1 事务拦截器(TransactionInterceptor)

2.2 事务管理器(PlatformTransactionManager)

3 属性

3.1 timeout 超时限制

3.2. readOnly 只读优化

3.3 rollbackFor 回滚指明

3.4 norollbackFor不回滚指明

3.5 propagation 事务的传播行为

3.6 小事务如果与大事务共用一个事务,那小事务按照大事务的属性设置,小事务的失效

三 内容补充

eg:具体使用举例


一 Spring数据库的相关配置:

1 导入包:

2 配置数据库连接信息

3 可以直接使用:DataSource,JdbcTemplate

二 事务管理:

1 声明式

声明式VS编程式

声明式:通过注解等方式,告诉框架,我需要做什么,框架会帮我做什么。

优点:代码量少

缺点:封装太多,排错不容易。

编程式:通过代码的方式,告诉框架,我要做什么,需要自己写代码实现。

优点:排错容易

缺点:代码量多

1 事务管理的实现

1.1 开启Spring事务管理
//开启事务
@EnableTransactionManagement
@SpringBootApplication
public class Spring03Application {

    public static void main(String[] args) {
        SpringApplication.run(Spring03Application.class, args);
        
    }

}
1.2 为指定方法添加事务

2 关键类与接口

类/接口作用
PlatformTransactionManager事务操作的核心接口(提交、回滚等)。
TransactionInterceptor拦截方法调用,管理事务边界。(切面)
TransactionAttributeSource解析@Transactional的属性。
BeanFactoryTransactionAttributeSourceAdvisor将事务通知应用到目标方法。
InfrastructureAdvisorAutoProxyCreator自动生成代理对象的Bean后处理器。
2.1 事务拦截器(TransactionInterceptor)
  • 拦截逻辑:代理对象会将方法调用委托给TransactionInterceptor(事务拦截器),该拦截器负责管理事务的开启、提交或回滚。

  • 事务属性解析:拦截器会解析@Transactional注解的属性(如propagationisolationrollbackFor等),决定事务的行为。

2.2 事务管理器(PlatformTransactionManager)
  • 事务操作:拦截器通过PlatformTransactionManager接口(如DataSourceTransactionManagerJpaTransactionManager)执行具体的事务操作:

    • getTransaction():根据传播行为决定是否创建新事务或加入现有事务。

    • commit():提交事务(如果当前是事务的发起者)。

    • rollback():回滚事务(在抛出异常时触发)。

3 属性

3.1 timeout 超时限制

(timeoutString也行)超时时间,事务超时,以秒为单位,一旦超过约定时间,事务就会回滚。

超时时间指的是从方法开始,到最后一次数据库操作的时间。

@Transactional(timeout = 10) // 单位:秒
public void doBusinessOperation() {
    // 业务逻辑
}

以下的sleep将不会计入超时时间的范畴

3.2. readOnly 只读优化

性能优化:通过声明只读事务提示底层资源进行优化,适用于纯查询场景。

合理使用readOnly=true可以提升查询性能,但需结合具体技术栈验证其行为。

@Transactional(readOnly = true) // 默认为false
public List<User> findAllUsers() {
    // 查询逻辑(不应包含INSERT/UPDATE/DELETE)
}
3.3 rollbackFor 回滚指明

通过rollbackFor自定义事务回滚的异常条件,覆盖默认行为。

  • 精确控制回滚条件:允许开发者明确指定某些特定异常(包括受检异常)触发事务回滚。

  • 覆盖默认行为:默认仅回滚未检查异常,通过rollbackFor可扩展或替换默认规则。

异常类型示例默认是否触发回滚说明
运行时异常(Unchecked)RuntimeExceptionNullPointerExceptionIllegalArgumentException继承自RuntimeException
错误(Error)OutOfMemoryErrorStackOverflowError继承自Error
编译时异常(Checked)IOExceptionSQLException继承自Exception(非RuntimeException)

由此我们使用回滚指明rollbackfor来调控回滚的时机

3.4 norollbackFor不回滚指明
  • 核心作用:通过noRollbackFor精准控制哪些异常不触发事务回滚,即使它们是默认回滚类型。

  • 适用场景

    • 需要忽略特定的非致命异常(如业务警告、预期内的错误)。

    • 覆盖框架或默认的异常回滚策略。

  • 关键原则

    • 明确异常类型,避免过度使用(如直接排除Exception.class可能导致数据不一致)。

    • 结合rollbackFor实现精细化的事务控制。

    • noRollbackFor优先级高于rollbackFor

3.5 propagation 事务的传播行为

传播行为类型及作用(小事务与大事务的绑定关系)

传播行为描述适用场景
REQUIRED(默认)如果当前存在事务,则加入该事务;否则新建一个事务。多数业务场景(如订单创建、库存扣减)。
SUPPORTS如果当前存在事务,则加入;否则以非事务方式运行。查询方法,允许在事务或非事务上下文中执行。
MANDATORY必须在已有事务中运行,否则抛出异常。强制要求调用方必须开启事务(如核心业务操作)。
REQUIRES_NEW无论当前是否存在事务,都新建一个独立事务,挂起当前事务(若存在)。需要独立提交的操作(如日志记录、异步任务)。
NOT_SUPPORTED以非事务方式执行,若当前存在事务,则挂起当前事务。不依赖事务的操作(如纯查询或外部接口调用)。
NEVER必须在非事务环境下执行,否则抛出异常。严格禁止事务的场合(如某些性能敏感操作)。

NESTED(保存点

:存档)

在已有事务中嵌套一个子事务(通过保存点实现),子事务可独立回滚。部分操作需要独立回滚(如批量处理中的单条失败)。仅部分数据库支持(如MySQL的InnoDB)。

3.6 小事务如果与大事务共用一个事务,那小事务按照大事务的属性设置,小事务的失效

1 传播行为
若小事务的传播行为为REQUIRED(默认),当它被大事务调用时,会直接加入大事务,而非创建新事务。

@Transactional(timeout = 30)  // 大事务
public void bigTransaction() {
    smallTransaction();  // 小事务
}

@Transactional(timeout = 10)  // 小事务(实际无效)
public void smallTransaction() {
    // 操作数据库
}

2. 小事务“失效”的具体表现

事务属性失效原因
超时(Timeout)大事务的timeout决定了整个事务的最长执行时间,小事务的timeout设置无效。
隔离级别(Isolation)事务的隔离级别在事务开始时确定,小事务无法修改已存在事务的隔离级别。
只读(ReadOnly)若大事务为读写模式,小事务的readOnly=true不生效(数据库连接仍为读写模式)。

三 内容补充

eg:实现方法

下面这种情况金额减了但是库存没有减,扣减金额跟随大事务,扣减库存开启自己的事务自己干

eg:具体使用举例

1 如果在上述位置放置运行时异常,那么根据分析:

C  I  J D K L F  H  N - 都是好的可以正常运行

2 如果在 L方法位置放置运行时异常,那么根据分析:

F  H  C  I J  K   都是好的可以正常  ( E这一段代码执行不到 )

3 如果在 M方法位置放置运行时异常,那么根据分析:

F  H  C  I  J  D  K   L 都是好的可以正常运行

1. REQUIRED(默认)

比喻场景团队合作做项目

  • 行为

    • 如果你加入时已经有团队在做项目(存在事务),你就直接跟着团队一起干(加入事务)。

    • 如果没人开始做(无事务),你就自己拉起一个团队(新建事务)。

  • 总结能跟团就跟团,没团就自己组队


2. SUPPORTS

比喻场景朋友聚餐AA制

  • 行为

    • 如果大家决定AA制(存在事务),你就跟着一起AA(加入事务)。

    • 如果没人提AA(无事务),你就自己单独付钱(非事务运行)。

  • 总结有团就随大流,没团就自己玩


3. MANDATORY

比喻场景必须团队合作的任务

  • 行为

    • 必须有人组队(存在事务)才能执行任务,否则直接罢工(抛出异常)。

    • 比如公司规定某些任务必须集体完成,不允许单干。

  • 总结没团队就罢工


4. REQUIRES_NEW

比喻场景临时插队的紧急任务

  • 行为

    • 无论你手头有没有任务(无论是否存在事务),都要暂停当前工作(挂起事务),先处理这个紧急任务(新建独立事务)。

    • 例如:正在写报告时,老板突然让你立刻发一封邮件(独立事务),发完邮件再继续写报告。

  • 总结天大的事也得先干我这个


5. NOT_SUPPORTED

比喻场景去图书馆自习

  • 行为

    • 你不想被其他人的讨论影响(挂起当前事务),选择自己安静看书(非事务运行)。

    • 例如:在团队开会时(存在事务),你突然去走廊接电话(非事务)。

  • 总结谁都别打扰我,我要自己静静


6. NEVER

比喻场景严禁团队合作的考试

  • 行为

    • 必须独自完成考试(非事务),如果发现有人组队作弊(存在事务),直接取消资格(抛出异常)。

  • 总结敢组队就挂科


7. NESTED

比喻场景项目中的子任务

  • 行为

    • 你在做一个大项目(外层事务),中途画了一部分设计稿(创建保存点)。

    • 如果设计稿有问题(子事务失败),可以只重画这部分(回滚到保存点),而不用推翻整个项目。

  • 总结大项目里的小草稿,错了只改这一页

相关文章:

  • Spring Boot中利用Redis解决接口幂等性问题
  • GPIO接口
  • Django ORM自定义排序的实用示例
  • Axure RP 9 安装与汉化指南(附安装包)包含下载、安装、汉化、授权,Axure9 汉化教程、Axure9 汉化步骤
  • MoonSharp 文档三
  • Rust规律归纳随笔
  • 使用Mermaid语法绘制的C语言程序从Linux移植到Windows的流程图
  • Leetcode8-字符串转换整数(atoi)
  • 【技术白皮书】内功心法 | 第二部分 | Telnet远程登录的工作原理
  • 大模型:定义与主流架构全解析
  • 【TVM教程】为 Mobile GPU 自动调优卷积网络
  • SwiftUI 让视图自适应高度的 6 种方法(四)
  • Kubernetes Pod的生命周期概述
  • LearnOpenGL-笔记-其二
  • DeepSeek-实用集成大礼包
  • 基于某著名企业IPD与质量管理体系融合的研发质量管理方案(64页PPT)
  • 【保姆级教程】使用 oh-my-posh 和 clink 打造个性化 PowerShell 和 CMD
  • 十二天-双指针技术:链表问题的高效解法
  • springboot433-基于SpringBoot的流浪猫爱心救助系统(源码+数据库+纯前后端分离+部署讲解等)
  • Fast DDS Security--多方密钥协商协议
  • 多个侵华日军细菌战部队留守名簿文件首次公布
  • 上海下周最高气温在30℃附近徘徊,夏天越来越近
  • 傅利叶提出下个十年战略,CEO顾捷:机器人要有温度,要用实际价值来定义形态
  • 国家卫健委:有条件的二级及以上综合医院要开设老年医学科
  • 上海今日降雨降温,节后首个工作日气温回升最高可达28℃
  • 当一群杜克土木工程毕业生在三四十年后怀念大学的历史课……