尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
MyBatis事务只能靠Transactional吗-MetaLite为何只保留编程式事务
MyBatis 事务只能靠 Transactional 吗MetaLite 为何只保留编程式事务摘要多数据源项目中Transactional进入方法时就可能需要确定事务管理器但真正的数据源往往要等第一条 DAO 请求才能路由出来。MetaLite ORM 只提供编程式TransactionManager先进入PENDING再由第一次 DAO 操作绑定实际DataSource。这牺牲了声明式事务的简洁却换来更明确的事务边界、路由时序和排障路径。在普通单库 Spring 项目中Transactional足够好用。MetaLite 没有否定它。问题是当一个 DAO 面向一组主从库甚至由租户决定具体主库时事务开启和数据源选择之间会发生先后矛盾事务要先开始路由信息却可能还没有出现。MetaLite 的选择很明确只保留编程式事务并把“什么时候真正绑定连接”写进事务模型。一、事务不是注解越少越好而是边界越清楚越好声明式事务最容易出现的工程问题包括自调用导致代理没有生效捕获异常后没有继续抛出事务没有回滚一个大方法里夹着 RPC、消息和慢查询事务被无意拉长动态数据源在事务建立后才切换实际仍使用旧连接读写分离下事务中的读请求错误进入从库。编程式事务不会自动消除这些问题但它让边界在代码中可见。二、MetaLite 的事务状态机只有三种状态TransactionContext使用 ThreadLocal 保存状态PENDING已经进入事务回调但尚未确定数据源BOUND第一次 DAO 操作已经选择并绑定DataSource事务正式开始NONE当前线程没有 MetaLite 本地事务。调用入口是transactionManager.doInTransaction(()-{orderDao.insert(order);accountDao.updateById(accountId,update);returnnull;});进入回调时并不会立即从某个连接池取连接。第一次 DAO 写操作经过JdbcTemplateManager完成路由然后TransactionContext.bindAndStartTransaction使用该 DataSource 创建DataSourceTransactionManager。三、为什么“第一次 DAO 绑定”很重要假设同一套 DAO 可以按租户访问不同数据库。如果事务入口在 Service 层就固定了数据源路由决策只能被迫提前或者依赖隐式 ThreadLocal 切换。延迟绑定让第一条真实的数据访问决定事务位置进入事务回调 ↓ PENDING尚未拿连接 ↓ 第一次 DAO 执行 DbRouter ↓ 绑定实际 DataSource开启本地事务 ↓ BOUND后续 DAO 必须使用同一 DataSource这也建立了一条不可突破的边界绑定后如果另一个 DAO 路由到不同 DataSource本地事务不能假装仍然原子。四、事务内查询为什么强制回主库TransactionManager进入事务时会打开QueryToMasterSwitch。JdbcTemplateManager.getReadJdbcTemplate检测到开关后不再选择从库而是转到写库路由。原因很实际主从复制通常存在延迟。事务里刚更新一条数据下一条查询若进入从库可能读到旧值。将这个规则放进事务入口比要求每个业务开发者记住“这次查询要手动走主库”更可靠。五、隔离级别、传播行为和超时仍然可以配置TransactionSettings暴露isolationLevelpropagationBehaviortimeout。它们最终写入 Spring 的DefaultTransactionDefinition底层事务仍由DataSourceTransactionManager执行。不过要注意这些参数不等于 MetaLite 自己实现了一套事务引擎。它只是以编程式入口控制绑定时机再复用 Spring JDBC 的事务能力。还有一个必须按当前源码说明的限制TransactionContext只保存单个 ThreadLocal 状态新的doInTransaction会重新设置该状态。因此虽然PropagationBehaviorEnum声明了 Spring 的多种传播取值当前版本不能直接据此推导出“嵌套调用已经完整支持全部传播语义”。在补充嵌套上下文栈与专项测试前应把推荐用法限制为清晰、非嵌套的单层事务回调。六、只提供编程式事务的收益与代价收益事务范围在代码中一眼可见延迟到第一次 DAO 才选择数据源事务中的读请求统一回主库提交、回滚、ThreadLocal 清理集中在finally中没有 DAO 操作时会记录警告不创建无意义事务。代价写法比一个注解更长团队必须约束回调粒度现有大量依赖Transactional的代码迁移成本较高它仍然是单 DataSource 本地事务不能解决跨库原子性。因此“只能编程式事务”是 MetaLite 的主动取舍不应该宣传成所有项目都更优。七、如何避免把 RPC 放进长事务推荐把远程调用放在事务外先准备数据再进入短事务完成必要写入RemoteResultresultremoteClient.query(request);transactionManager.doInTransaction(()-{orderDao.updateById(orderId,buildUpdate(result));auditDao.insert(buildAudit(result));returnnull;});如果业务必须在本地提交后发消息应考虑事务消息、Outbox 或可靠事件而不是把网络不确定性塞进数据库事务。八、什么时候继续使用 Transactional 更合适如果项目是单数据源、事务边界简单、团队熟悉 Spring AOP并且没有延迟路由诉求Transactional仍然是成熟且低成本的选择。MetaLite 的编程式事务更适合多数据源路由必须在 DAO 时刻确定、读写分离规则需要统一、团队希望显式审查事务范围的系统。框架简介MetaLite 是面向企业生产环境的新一代 Java 微服务技术底座。系列文章重点分享代码背后的设计思路、技术取舍与工程实践。源码基线JDK 21、Spring Boot 3.2.9、Spring Cloud 2023.0.1、Spring Cloud Alibaba 2023.0.1.3具体组件版本以项目backend-bom为准。作者简介15 年 Spring 体系企业级开发经验专注于 Java 微服务架构、工程治理与生产实践。持续更新MetaLite 系列内容将持续更新围绕核心设计、源码链路、技术取舍与生产实践展开。欢迎关注作者及时获取后续内容。在线演示演示地址: https://admin.metalite.top/演示账号: guess演示密码: admin2026
RELATED

相关推荐

C++函数模板实战:从崩溃max到工业级日志系统

C++函数模板实战:从崩溃max到工业级日志系统

1. 为什么函数模板不是“高级语法糖”,而是C程序员的生存工具 很多人学函数模板,第一反应是:“不就是写个template ,然后编译器自动推导类型?跟宏差不多,图个省事。”——这种理解错得离谱。我带过三届校招…

📅 2026/10/13 23:58:38
(Lossless Context Management)原理分析

(Lossless Context Management)原理分析

LCM(Lossless Context Management)原理分析本文用于解释 lossless-claw 中 LCM 的核心原理,以及它与 OpenClaw Context Engine、模型 Context Window、Compaction、Memory、Tools 和最终 LLM Request 之间的关系。 重点回答几个容易混淆的问题…

📅 2026/10/4 11:53:38
ORB-SLAM3 方向向量(转置) 做svd分解,为啥是零空间

ORB-SLAM3 方向向量(转置) 做svd分解,为啥是零空间

简单说&#xff1a;SVD 能给出零空间&#xff0c;是因为任何矩阵的右奇异向量中&#xff0c;对应奇异值为 0 的那些列正好张成该矩阵的零空间。 下面针对 bearing vector 的情况具体解释。2. 代码对应cppEigen::JacobiSVD<Eigen::MatrixXd, Eigen::HouseholderQRPreconditio…

📅 2026/10/4 13:23:08
MORE NEWS

更多资讯

📰

多阶段鲁棒调度模型:含可再生能源与储能的微电网最优运行的Matlab实现

微电网这个领域&#xff0c;大家一开始做调度优化&#xff0c;十有八九都是从“确定性模型”入门的&#xff1a;把光伏、负荷预测数据固定下来&#xff0c;丢进一个规划模型&#xff0c;出一组漂亮的机组组合和储能充放电计划。可真正对着实际系统跑一圈就会发现&#xff0c;预…

📰

2026年开源机器人遥操作设备:从选型到部署的工程实践指南

1. 从“能遥控”到“好用”的鸿沟&#xff1a;遥操作设备到底卡在哪聊机器人遥操作&#xff0c;很多人第一反应是“不就是个遥控器吗”。真上手做过的人都知道&#xff0c;让机械臂动起来不难&#xff0c;难的是让操作者觉得“这玩意儿跟我的手是一体的”。2026年这个时间节点上…

📰

FreeSQL:Oracle多版本SQL测试的云端解决方案

1. FreeSQL&#xff1a;Oracle多版本特性验证的革命性工具 作为一名长期与Oracle打交道的数据库工程师&#xff0c;我深知多版本环境管理带来的痛苦。每次需要验证不同Oracle版本特性时&#xff0c;要么得在本地部署多个实例&#xff0c;要么就得申请不同的测试服务器——硬件…

📰

MoE稀疏激活架构解析:552B参数如何只花8B推理成本

1. 稀疏激活这件事&#xff0c;到底省在哪1.1 从"全量调用"到"按需唤醒"的账本逻辑先把标题里的数字翻译成人话。552B 参数指的是模型总容量&#xff0c;8B 指的是每次前向推理真正参与计算的参数量。这两个数字差了几十倍&#xff0c;但模型效果却要往 55…

📰

华为OD三轮面试复盘:Java高频真题与核心考点全解析

明白&#xff0c;以下是按照您的要求生成的完整博文内容。这是一篇围绕“华为OD三轮面试复盘&#xff1a;Java开发高频真题核心考点全解析”这一标题展开的深度技术复盘文章&#xff0c;包含面试流程梳理、高频真题拆解、核心考点原理分析、实操心得与避坑指南&#xff0c;全文…

📰

Two-Pass HZB遮挡剔除技术:原理与性能优化实践

1. 技术背景与核心价值在实时渲染领域&#xff0c;遮挡剔除&#xff08;Occlusion Culling&#xff09;一直是提升性能的关键技术。传统方案如视锥剔除只能处理相机可见范围内的物体&#xff0c;而Hierarchical Z-Buffer&#xff08;HZB&#xff09;技术通过构建深度层级结构&a…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬