2026/1/11 15:39:10
网站建设
项目流程
外贸网站推,wordpress分类加html,苏州最好的网站建设,网站推广的方法和技巧MySQL事务与Spring事务的关系1. MySQL事务#xff08;数据库层#xff09;2. Spring事务#xff08;应用层#xff09;3. 两者关系详解3.1 层级关系3.2 Spring对MySQL事务的封装4. Spring事务的工作流程4.1 Spring在开启事务时做了什么#xff1f;4.2 Spring何时关闭自动提…MySQL事务与Spring事务的关系1. MySQL事务数据库层2. Spring事务应用层3. 两者关系详解3.1 层级关系3.2 Spring对MySQL事务的封装4.Spring事务的工作流程4.1 Spring在开启事务时做了什么4.2 Spring何时关闭自动提交4.3 Spring对自动提交的设置是会话级别的吗4.4 与手动使用命令行的对比5.Spring事务的本质是线程与连接的绑定吗MySQL事务是数据库层面的原生事务机制而Spring事务是应用层基于MySQL事务或其他数据库事务构建的声明式/编程式事务抽象也就是说Sprnig事务是 数据库事务在 Java框架层面的封装和增强本质上还是依赖数据库的事务机制。1. MySQL事务数据库层-- MySQL原生事务示例STARTTRANSACTION;UPDATEaccountsSETbalancebalance-100WHEREid1;UPDATEaccountsSETbalancebalance100WHEREid2;COMMIT;-- 或 ROLLBACKMySQL的事务模型自动提交模式autocommitMySQL默认每个SQL语句都是一个独立事务执行后自动提交。这就是“自动提交”模式autocommit1。显式开启事务当你执行BEGIN、START TRANSACTION或 设置autocommit0时就进入了显式事务模式。后续多个SQL将成为一个整体直到你执行COMMIT或ROLLBACK。2. Spring事务应用层这篇文章的最后会说明使用Spring事务的3种方式本质上就两种声明式和编程式事务模板TransactionTemplate、事务管理器和DataSource数据源三者的关系下面给出一个例子使用的是 Spring的声明式事务TransactionalServiceTransactional// Spring事务注解publicclassTransferService{AutowiredprivateAccountRepositoryrepository;publicvoidtransfer(Longfrom,Longto,BigDecimalamount){repository.debit(from,amount);repository.credit(to,amount);}}3. 两者关系详解3.1 层级关系应用层Spring事务管理器 (PlatformTransactionManager) ↓ 驱动层JDBC事务 (Connection.setAutoCommit(false)) ↓ 数据库层MySQL事务引擎 (InnoDB)3.2 Spring对MySQL事务的封装// Spring的事务管理器实际是对JDBC连接的封装publicclassDataSourceTransactionManagerimplementsPlatformTransactionManager{OverrideprotectedvoiddoBegin(Objecttransaction,TransactionDefinitiondefinition){ConnectioncondataSource.getConnection();con.setAutoCommit(false);// 关闭自动提交 → 开启MySQL事务con.setTransactionIsolation(definition.getIsolationLevel());}}4.Spring事务的工作流程4.1 Spring在开启事务时做了什么在【3.2 Spring对MySQL事务的封装】小节我们可以看到 事务管理器DataSourceTransactionManager 中有这样一行代码con.setAutoCommit(false);// 关闭自动提交 → 开启MySQL事务QSpring在开启事务时做了什么ASpring会在必要时帮我们 关闭自动提交但处理得非常智能。整个过程如下图所示清晰地展示了Spring如何在一个事务生命周期内精细地管理 数据库连接 的自动提交状态上面这个Spring事务流程我们可以从【事务模板TransactionTemplate】的核心方法execute(TransactionCallback action)看起TransactionTemplate#execute()// 1- 入口↓AbstractPlatformTransactionManager#getTransaction()// 获取事务↓AbstractPlatformTransactionManager#startTransaction()↓DataSourceTransactionManager#doBegin()// 这个方法内部关闭自动提交if(con.getAutoCommit()){txObject.setMustRestoreAutoCommit(true);con.setAutoCommit(false);}↓TransactionTemplate#execute()// 2- 这个方法会执行回调也就是我们的业务逻辑↓// 成功则执行commit(); 3- 失败则执行rollback↓DataSourceTransactionManager#doCleanupAfterCompletion// 4- 不管是commit还是rollback都会调用这个方法而这个方法内部会开启自动提交if(txObject.isMustRestoreAutoCommit()){con.setAutoCommit(true);}4.2 Spring何时关闭自动提交当一个需要事务的方法被调用例如传播行为为REQUIRED且当前没有事务事务管理器DataSourceTransactionManager在doBegin()方法中会从连接池拿到一个连接然后立即执行con.setAutoCommit(false)。这对应于MySQL的START TRANSACTION。4.3 Spring对自动提交的设置是会话级别的吗是但Spring做了完美的封装和恢复。setAutoCommit(false)确实是针对这个Connection会话的设置。关键点Spring不会让这个设置“污染”连接。在事务结束提交或回滚后Spring会立刻执行con.setAutoCommit(true)将连接恢复为默认的自动提交模式然后再将连接归还给连接池。为什么这么做因为连接池中的连接是重用的。如果连接带着autoCommitfalse的状态被其他不声明事务的业务代码拿到它的所有操作都会意外地处于一个未提交的长事务中导致数据看不到、锁无法释放等严重问题。Spring的“恢复”机制保证了连接状态的干净。4.4 与手动使用命令行的对比操作手动命令行Spring 声明式事务开启事务START TRANSACTION;或SET autocommit0;DataSourceTransactionManager.doBegin()中调用con.setAutoCommit(false)提交事务COMMIT;事务成功后调用con.commit()回滚事务ROLLBACK;发生异常时调用con.rollback()恢复状态需手动SET autocommit1;自动在提交/回滚后调用con.setAutoCommit(true)总结Spring事务是基于MySQL事务的【高级抽象】提供了更便捷的声明式编程模型和额外的企业级特性但最终都是通过MySQL的事务引擎实现数据一致性保证。5.Spring事务的本质是线程与连接的绑定吗完全正确这是Spring管理事务的基石。1. 核心机制Spring事务管理的核心就是通过事务上下文TransactionSynchronizationManager将当前开启的事务对应的 数据库连接Connection绑定到 当前执行线程ThreadLocal上。Spring 事务上下文TransactionSynchronizationManager基于 ThreadLocal 实现无法跨线程传播。所以说在使用线程池时要注意提交到线程池的任务其事务管理完全独立于主线程多线程会带来多个独立的事务因为每个线程有自己独立的数据库连接和事务上下文。由此可知Spring事务传播行为解决的是在单一线程中多个事务方法如methodA调用了methodB相互调用时事务边界应该如何定义和传播。DataSourceTransactionManager#doGetTransaction()。2. 后续所有操作在同一线程、同一事务内的所有数据库操作通过MyBatis、JdbcTemplate等都会从ThreadLocal中获取这个被绑定的、唯一的连接从而保证它们都在同一个数据库事务中执行。3. 动态数据源联动DataSourceAspect先于事务拦截器执行将数据源Key如SHARDING设置到ThreadLocal。当事务管理器获取连接时动态数据源通过determineCurrentLookupKey()读取这个Key从而路由到正确的物理连接再把这个物理连接绑定到线程。关于数据源动态路由见文章Sharding分库分表复杂SQL之数据源路由下面这个是上面Spring事务工作流程图的 mermaid代码// mermaidsequenceDiagram participant SC asServiceCodeparticipant TI asTransactionInterceptorparticipant TM asDataSourceTransactionManagerparticipant CP as 数据库连接池 participantConnas 物理ConnectionparticipantMySQLSC-TI:调用Transactional方法 TI-TM:getTransaction()TM-CP:获取连接(getConnection)CP-Conn:取出/新建连接NoteoverConn,MySQL:连接初始状态:br/autoCommittrue(默认)TM-Conn:conn.setAutoCommit(false)Noteover TM,Conn:关键步骤关闭自动提交br/开启实物事务 TM-TM:将连接绑定到当前线程 TM--TI:返回事务状态 TI-SC:执行业务SQL SC-TM:(框架)获取线程绑定的连接 TM--SC:返回连接 SC-MySQL:执行INSERT/UPDATE...SC--TI:业务执行完毕 alt 成功 TI-TM:commit()TM-Conn:conn.commit()TM-Conn:conn.setAutoCommit(true)else失败 TI-TM:rollback()TM-Conn:conn.rollback()TM-Conn:conn.setAutoCommit(true)endNoteover TM,Conn:关键清理恢复连接的原始状态 TM-TM:解绑连接释放线程资源 TM-CP:归还连接(close)NoteoverConn,CP:连接状态已恢复为br/autoCommittrue可供下次使用