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

如果二者隔离级别不一致,以哪个为主。例如@Transactional 隔离级别是RC,mysql是RR

如果 Spring 的 @Transactional 隔离级别 和 数据库的隔离级别 不一致,最终生效的隔离级别取决于以下两种情况:


1. Spring 隔离级别优先级更高

  • Spring 的行为

    • 当你在 @Transactional 注解中显式配置了隔离级别(例如 isolation = Isolation.READ_COMMITTED),Spring 会在开启事务时向数据库发送 SET TRANSACTION ISOLATION LEVEL <级别> 的指令。

    • 例如:

      sql

      复制

      SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
    • 这样会覆盖数据库的默认隔离级别。

  • 生效的隔离级别

    • 以 Spring 配置的隔离级别为准。

    • 例如,@Transactional(isolation = Isolation.READ_COMMITTED) 会强制将事务的隔离级别设置为 READ COMMITTED,即使数据库的默认隔离级别是 REPEATABLE READ


2. 数据库隔离级别优先级更高

  • 数据库的限制

    • 如果数据库不支持 Spring 配置的隔离级别,数据库会忽略 Spring 的配置,使用数据库的默认隔离级别。

    • 例如:

      • Oracle 不支持 READ UNCOMMITTED 和 REPEATABLE READ

      • 如果 Spring 配置了 isolation = Isolation.READ_UNCOMMITTED,而数据库是 Oracle,Spring 会抛出异常或回退到数据库支持的隔离级别。

  • 生效的隔离级别

    • 以数据库支持的隔离级别为准。

    • 例如,如果 Spring 配置了 isolation = Isolation.READ_UNCOMMITTED,而数据库是 MySQL,则生效的隔离级别是 READ UNCOMMITTED;但如果数据库是 Oracle,则会回退到 READ COMMITTED


3. 你的问题:Spring 配置为 RC,MySQL 默认是 RR

  • 情况分析

    • Spring 配置了 @Transactional(isolation = Isolation.READ_COMMITTED),即 RC

    • MySQL 的默认隔离级别是 REPEATABLE READ,即 RR

  • 最终生效的隔离级别

    • 以 Spring 配置的隔离级别为准,即 READ COMMITTED

    • 因为 MySQL 支持 READ COMMITTED,Spring 会在开启事务时发送 SET TRANSACTION ISOLATION LEVEL READ COMMITTED 的指令,覆盖 MySQL 的默认隔离级别。


4. 验证方法

你可以通过以下方式验证事务的隔离级别是否生效:

(1) 查看当前事务的隔离级别

在 MySQL 中,可以通过以下 SQL 查询当前会话的隔离级别:

sql

复制

SELECT @@tx_isolation; -- MySQL 5.x
SELECT @@transaction_isolation; -- MySQL 8.x
(2) 测试隔离级别的行为
  • 开启两个事务:

    • 事务 A:更新数据但不提交。

    • 事务 B:查询数据。

  • 根据隔离级别的不同,事务 B 的查询结果会有所不同:

    • 如果隔离级别是 READ COMMITTED,事务 B 看不到事务 A 未提交的数据。

    • 如果隔离级别是 READ UNCOMMITTED,事务 B 可以看到事务 A 未提交的数据。


5. 代码示例

以下是一个 Spring 配置 READ COMMITTED 隔离级别的示例:

java

复制

@Service
public class OrderService {

    @Autowired
    private OrderRepository orderRepository;

    // 使用 READ COMMITTED 隔离级别
    @Transactional(isolation = Isolation.READ_COMMITTED)
    public void updateOrder(Order order) {
        orderRepository.save(order);
    }

    // 查询方法
    @Transactional(isolation = Isolation.READ_COMMITTED)
    public Order getOrder(Long orderId) {
        return orderRepository.findById(orderId).orElse(null);
    }
}

6. 总结

  • Spring 配置的隔离级别优先级更高

    • 如果 Spring 显式配置了隔离级别,且数据库支持该级别,则以 Spring 配置为准。

    • 例如,Spring 配置 READ COMMITTED,MySQL 默认是 REPEATABLE READ,最终生效的是 READ COMMITTED

  • 数据库的限制

    • 如果数据库不支持 Spring 配置的隔离级别,则以数据库支持的隔离级别为准。

  • 验证方法

    • 可以通过 SQL 查询或测试事务行为来验证隔离级别是否生效。

如果你有更多问题,欢迎继续讨论!

@Transactional(readOnly = true)什么含义

相关文章:

  • MySQL安装
  • Docker 与 CI/CD:自动化构建和部署
  • MySQL数据库——索引结构之B+树
  • flowable 全生命周期涉及到的api及mysql表
  • nextjs项目搭建——头部导航
  • 【数论】—— 快速幂与扩展欧拉定理
  • 【Web开发】PythonAnyWhere免费部署Django项目
  • 第六次作业
  • python类型转换深浅拷贝
  • 了解Pipx:一个轻量但强大的Python工具
  • 如何在 SpringBoot 项目创建并使用 Redis 的详细介绍
  • 【漫话机器学习系列】103.学习曲线(Learning Curve)
  • 蓝桥杯之阶段考核
  • 跟李沐学AI:InstructGPT论文精读(SFT、RLHF)
  • 《Mycat核心技术》第17章:实现MySQL的读写分离
  • 网络安全入门 | TCP/IP协议栈核心协议详解(附攻防案例)
  • 基于AT89C51单片机的教室智能照明控制系统
  • 软件工程和系统分析与设计
  • 前端性能测试优化案例
  • Python 调用 DeepSeek API 完整指南
  • 网站制作的评价标准/seo搜索排名优化方法
  • 导购网站制作/建站软件
  • 网站建设的特色/怎么去优化关键词
  • 为什么做的网站在浏览器搜不到/台湾新闻最新消息今天
  • 买了域名和空间怎么做网站/谷歌广告投放
  • 网站建设与案例管理的心得体会/一个网站的seo优化有哪些