wap网站系统,企业咨询公司收费标准,网站制作需要什么人员,网站开发英文合同在白嫖之前#xff0c;希望你会内疚#xff0c;最起码点个赞收藏再自取吧#xff0c;源码在最后#xff0c;自取#xff1b;
在白嫖之前#xff0c;希望你会内疚#xff0c;最起码点个赞收藏再自取吧#xff0c;源码在最后#xff0c;自取#xff1b;
在白嫖之前希望你会内疚最起码点个赞收藏再自取吧源码在最后自取在白嫖之前希望你会内疚最起码点个赞收藏再自取吧源码在最后自取在白嫖之前希望你会内疚最起码点个赞收藏再自取吧源码在最后自取本文从底层原理核心代码角度拆解AOP实现事务控制的完整逻辑重点分析Spring事务管理器PlatformTransactionManager的核心实现以及AOP如何通过环绕通知织入事务逻辑。所有代码均为可理解的核心简化版保留Spring原生逻辑但剔除冗余便于学习核心思路。一、核心前置知识1. 事务的本质数据库层面事务的底层是数据库连接java.sql.Connection的特性默认autoCommittrue执行每条SQL后自动提交开启事务connection.setAutoCommit(false)提交connection.commit()回滚connection.rollback()。Spring事务的本质是通过AOP拦截方法统一管理数据库连接的事务状态让业务代码无需感知连接操作。2. AOP实现事务的核心角色角色作用事务管理器PlatformTransactionManager封装事务的开启/提交/回滚逻辑对接数据库连接事务拦截器TransactionInterceptorAOP环绕通知的核心实现触发事务管理器操作动态代理JDK/CGLIB为业务类生成代理对象接管方法调用事务注解Transactional标记需要事务增强的方法定义事务属性传播行为、隔离级别等二、手写简化版AOP事务框架理解底层先通过手写核心代码模拟Spring事务的实现逻辑掌握AOP事务的核心思路。步骤1定义事务注解模拟Transactionalimportjava.lang.annotation.*;/** * 自定义事务注解标记需要事务控制的方法 */Target({ElementType.METHOD})Retention(RetentionPolicy.RUNTIME)DocumentedpublicinterfaceMyTransactional{// 模拟事务传播行为简化版Propagationpropagation()defaultPropagation.REQUIRED;// 事务隔离级别简化版Isolationisolation()defaultIsolation.DEFAULT;// 异常回滚规则Class?extendsThrowable[]rollbackFor()default{Exception.class};}// 传播行为枚举简化enumPropagation{REQUIRED// 默认有事务则加入无则新建}// 隔离级别枚举简化enumIsolation{DEFAULT// 使用数据库默认隔离级别}步骤2实现事务管理器模拟DataSourceTransactionManagerimportorg.springframework.jdbc.datasource.DataSourceUtils;importjavax.sql.DataSource;importjava.sql.Connection;importjava.sql.SQLException;/** * 自定义事务管理器封装数据库连接的事务操作 * 核心绑定连接到当前线程ThreadLocal保证同线程内方法共用一个连接 */publicclassMyTransactionManager{// 数据源Spring中通过配置注入privatefinalDataSourcedataSource;// 线程本地变量存储当前线程的事务连接状态privatefinalThreadLocalTransactionInfothreadLocalnewThreadLocal();publicMyTransactionManager(DataSourcedataSource){this.dataSourcedataSource;}/** * 开启事务 */publicTransactionInfobegin(MyTransactionalannotation){// 1. 获取数据库连接Spring中通过DataSourceUtils保证线程绑定ConnectionconnDataSourceUtils.getConnection(dataSource);TransactionInfotxInfonewTransactionInfo();txInfo.setConn(conn);txInfo.setAnnotation(annotation);txInfo.setOldAutoCommit(true);// 保存原有autoCommit状态try{// 2. 关闭自动提交开启事务if(conn.getAutoCommit()){conn.setAutoCommit(false);txInfo.setOldAutoCommit(true);}// 3. 设置隔离级别简化版if(annotation.isolation()!Isolation.DEFAULT){conn.setTransactionIsolation(annotation.isolation().ordinal()1);}// 4. 将事务信息绑定到当前线程threadLocal.set(txInfo);returntxInfo;}catch(SQLExceptione){thrownewRuntimeException(开启事务失败,e);}}/** * 提交事务 */publicvoidcommit(TransactionInfotxInfo){if(txInfonull)return;ConnectionconntxInfo.getConn();try{if(conn!null!conn.isClosed()){conn.commit();// 提交事务// 恢复原有autoCommit状态conn.setAutoCommit(txInfo.isOldAutoCommit());}}catch(SQLExceptione){thrownewRuntimeException(提交事务失败,e);}finally{// 释放连接清空线程变量DataSourceUtils.releaseConnection(conn,dataSource);threadLocal.remove();}}/** * 回滚事务 */publicvoidrollback(TransactionInfotxInfo){if(txInfonull)return;ConnectionconntxInfo.getConn();try{if(conn!null!conn.isClosed()){conn.rollback();// 回滚事务conn.setAutoCommit(txInfo.isOldAutoCommit());}}catch(SQLExceptione){thrownewRuntimeException(回滚事务失败,e);}finally{DataSourceUtils.releaseConnection(conn,dataSource);threadLocal.remove();}}// 事务信息封装类publicstaticclassTransactionInfo{privateConnectionconn;privateMyTransactionalannotation;privatebooleanoldAutoCommit;// getter/setter 省略}}步骤3实现AOP环绕通知事务拦截器importorg.aspectj.lang.ProceedingJoinPoint;importorg.aspectj.lang.annotation.Around;importorg.aspectj.lang.annotation.Aspect;importorg.aspectj.lang.reflect.MethodSignature;importjava.lang.reflect.Method;/** * 自定义事务拦截器AOP环绕通知核心逻辑 * 作用拦截MyTransactional注解的方法织入事务开启/提交/回滚逻辑 */AspectpublicclassMyTransactionInterceptor{// 事务管理器Spring中通过依赖注入privatefinalMyTransactionManagertransactionManager;publicMyTransactionInterceptor(MyTransactionManagertransactionManager){this.transactionManagertransactionManager;}/** * 环绕通知拦截所有标注MyTransactional的方法 */Around(annotation(com.example.MyTransactional))publicObjectintercept(ProceedingJoinPointjoinPoint)throwsThrowable{// 1. 获取方法上的事务注解MethodSignaturesignature(MethodSignature)joinPoint.getSignature();Methodmethodsignature.getMethod();MyTransactionalannotationmethod.getAnnotation(MyTransactional.class);MyTransactionManager.TransactionInfotxInfonull;try{// 2. 开启事务txInfotransactionManager.begin(annotation);// 3. 执行原始业务方法核心调用目标方法ObjectresultjoinPoint.proceed();// 4. 提交事务transactionManager.commit(txInfo);returnresult;}catch(Throwablee){// 5. 异常回滚判断是否符合回滚规则if(isRollback(e,annotation.rollbackFor())){transactionManager.rollback(txInfo);}throwe;// 抛出异常上层可感知}}/** * 判断异常是否需要回滚 */privatebooleanisRollback(Throwablee,Class?extendsThrowable[]rollbackFor){for(Class?extendsThrowableclazz:rollbackFor){if(clazz.isInstance(e)){returntrue;}}returnfalse;}}步骤4配置类开启AOP注入组件importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.context.annotation.EnableAspectJAutoProxy;importorg.springframework.jdbc.datasource.DriverManagerDataSource;importjavax.sql.DataSource;/** * 配置类组装AOP事务的核心组件 */ConfigurationEnableAspectJAutoProxy// 开启AOP动态代理publicclassTransactionConfig{// 1. 配置数据源BeanpublicDataSourcedataSource(){DriverManagerDataSourcedataSourcenewDriverManagerDataSource();dataSource.setDriverClassName(com.mysql.cj.jdbc.Driver);dataSource.setUrl(jdbc:mysql://localhost:3306/test?useSSLfalse);dataSource.setUsername(root);dataSource.setPassword(123456);returndataSource;}// 2. 配置自定义事务管理器BeanpublicMyTransactionManagermyTransactionManager(DataSourcedataSource){returnnewMyTransactionManager(dataSource);}// 3. 配置事务拦截器AOP切面BeanpublicMyTransactionInterceptormyTransactionInterceptor(MyTransactionManagertransactionManager){returnnewMyTransactionInterceptor(transactionManager);}}步骤5业务层使用自定义事务注解importorg.springframework.stereotype.Service;importjavax.annotation.Resource;importjava.sql.Connection;importjava.sql.PreparedStatement;importjava.sql.SQLException;ServicepublicclassOrderService{ResourceprivateDataSourcedataSource;/** * 标记需要事务控制的业务方法 */MyTransactional(rollbackFor{Exception.class})publicvoidcreateOrder(LongproductId,Integernum)throwsSQLException{// 业务逻辑1扣减库存deductStock(productId,num);// 业务逻辑2创建订单模拟异常如果num10则抛异常触发回滚if(num10){thrownewRuntimeException(库存超出限制);}createOrderRecord(productId,num);}// 扣减库存privatevoiddeductStock(LongproductId,Integernum)throwsSQLException{StringsqlUPDATE stock SET num num - ? WHERE product_id ?;try(ConnectionconndataSource.getConnection();PreparedStatementpsconn.prepareStatement(sql)){ps.setInt(1,num);ps.setLong(2,productId);ps.executeUpdate();}}// 创建订单记录privatevoidcreateOrderRecord(LongproductId,Integernum)throwsSQLException{StringsqlINSERT INTO order (product_id, num) VALUES (?, ?);try(ConnectionconndataSource.getConnection();PreparedStatementpsconn.prepareStatement(sql)){ps.setLong(1,productId);ps.setInt(2,num);ps.executeUpdate();}}}手写版核心逻辑总结注解标记通过MyTransactional标记需要事务的方法AOP拦截环绕通知拦截目标方法触发事务逻辑事务管理器封装数据库连接的autoCommit、commit、rollback操作线程绑定通过ThreadLocal保证同线程内的业务方法共用一个数据库连接核心否则多方法会用不同连接事务失效。三、Spring原生事务管理器深度解析Spring的PlatformTransactionManager是事务管理的核心接口我们基于手写版对比分析其原生实现。1. 核心接口体系// Spring事务管理器顶级接口publicinterfacePlatformTransactionManager{// 获取事务开启事务TransactionStatusgetTransaction(TransactionDefinitiondefinition)throwsTransactionException;// 提交事务voidcommit(TransactionStatusstatus)throwsTransactionException;// 回滚事务voidrollback(TransactionStatusstatus)throwsTransactionException;}// 事务定义传播行为、隔离级别、超时时间等publicinterfaceTransactionDefinition{intPROPAGATION_REQUIRED0;// 默认传播行为intISOLATION_DEFAULT-1;// 默认隔离级别// 省略其他常量方法}// 事务状态封装事务的连接、是否新建、是否回滚等publicinterfaceTransactionStatusextendsSavepointManager{booleanisNewTransaction();// 是否是新建事务booleanhasSavepoint();// 是否有保存点voidsetRollbackOnly();// 标记为回滚booleanisRollbackOnly();// 是否需要回滚voidflush();// 刷新事务booleanisCompleted();// 事务是否完成}2. 核心实现类DataSourceTransactionManagerDataSourceTransactionManager是JDBC/MyBatis场景下的核心实现核心方法拆解1开启事务getTransaction()OverridepublicTransactionStatusgetTransaction(TransactionDefinitiondefinition)throwsTransactionException{// 1. 获取事务定义传播行为、隔离级别等TransactionDefinitiondef(definition!null?definition:TransactionDefinition.withDefaults());// 2. 获取数据源连接绑定到当前线程ObjecttransactiondoGetTransaction();booleandebugEnabledlogger.isDebugEnabled();// 3. 处理传播行为核心判断是否新建事务/加入已有事务if(def.getPropagationBehavior()TransactionDefinition.PROPAGATION_REQUIRED){// 检查当前线程是否已有事务if(isExistingTransaction(transaction)){// 有事务则加入复用连接returnhandleExistingTransaction(def,transaction,debugEnabled);}// 无事务则新建if(def.getTimeout()TransactionDefinition.TIMEOUT_DEFAULT){thrownewInvalidTimeoutException(Invalid transaction timeout,def.getTimeout());}// 4. 开启新事务核心获取连接关闭autoCommitreturnstartNewTransaction(def,transaction,debugEnabled);}// 省略其他传播行为的处理...}// 核心开启新事务privateTransactionStatusstartNewTransaction(TransactionDefinitiondefinition,Objecttransaction,booleandebugEnabled){DataSourceTransactionObjecttxObject(DataSourceTransactionObject)transaction;// 5. 获取数据库连接通过DataSourceUtils保证线程绑定ConnectionconnDataSourceUtils.getConnection(obtainDataSource());txObject.setConnectionHolder(newConnectionHolder(conn),true);// 6. 关闭自动提交开启事务try{if(conn.getAutoCommit()){txObject.setMustRestoreAutoCommit(true);if(debugEnabled){logger.debug(Switching JDBC Connection [conn] to manual commit);}conn.setAutoCommit(false);}// 7. 设置隔离级别prepareTransactionalConnection(conn,definition);// 8. 标记事务为新建txObject.setNewTransaction(true);if(definition.isReadOnly()){txObject.setReadOnly(true);}// 9. 返回事务状态returnnewDefaultTransactionStatus(txObject,true,false,definition.isReadOnly(),debugEnabled,null);}catch(SQLExceptionex){DataSourceUtils.releaseConnection(conn,obtainDataSource());thrownewCannotCreateTransactionException(Could not open JDBC Connection for transaction,ex);}}2提交事务commit()Overridepublicvoidcommit(TransactionStatusstatus)throwsTransactionException{DefaultTransactionStatusdefStatus(DefaultTransactionStatus)status;// 1. 如果已标记回滚则直接回滚if(defStatus.isRollbackOnly()){processRollback(defStatus,false);return;}// 2. 非新建事务则不提交交给外层事务处理if(!defStatus.isNewTransaction()){if(defStatus.hasTransaction()){if(defStatus.isDebug()){logger.debug(Not committing JDBC transaction because its not a new transaction);}}return;}// 3. 新建事务则提交try{doCommit(defStatus);}catch(SQLExceptionex){thrownewTransactionSystemException(Could not commit JDBC transaction,ex);}finally{// 4. 释放连接恢复autoCommitcleanupAfterCompletion(defStatus.getTransaction());}}// 实际提交逻辑protectedvoiddoCommit(DefaultTransactionStatusstatus){DataSourceTransactionObjecttxObject(DataSourceTransactionObject)status.getTransaction();ConnectioncontxObject.getConnectionHolder().getConnection();if(status.isDebug()){logger.debug(Committing JDBC transaction on Connection [con]);}try{con.commit();// 数据库层面提交}catch(SQLExceptionex){thrownewTransactionSystemException(Could not commit JDBC transaction,ex);}}3回滚事务rollback()Overridepublicvoidrollback(TransactionStatusstatus)throwsTransactionException{DefaultTransactionStatusdefStatus(DefaultTransactionStatus)status;// 1. 非新建事务则标记回滚交给外层处理if(!defStatus.isNewTransaction()){if(defStatus.hasTransaction()){if(defStatus.isDebug()){logger.debug(Setting JDBC transaction rollback-only);}defStatus.setRollbackOnly();}return;}// 2. 新建事务则直接回滚processRollback(defStatus,false);}// 实际回滚逻辑privatevoidprocessRollback(DefaultTransactionStatusstatus,booleanunexpected){try{booleanrollbacktrue;// 处理保存点简化版忽略if(status.hasSavepoint()){if(status.isDebug()){logger.debug(Rolling back JDBC transaction to savepoint);}status.rollbackToSavepoint();rollbackfalse;}// 3. 回滚事务if(rollback){doRollback(status);}}catch(SQLExceptionex){thrownewTransactionSystemException(Could not roll back JDBC transaction,ex);}finally{// 4. 释放连接恢复autoCommitcleanupAfterCompletion(status.getTransaction());}}protectedvoiddoRollback(DefaultTransactionStatusstatus){DataSourceTransactionObjecttxObject(DataSourceTransactionObject)status.getTransaction();ConnectioncontxObject.getConnectionHolder().getConnection();if(status.isDebug()){logger.debug(Rolling back JDBC transaction on Connection [con]);}try{con.rollback();// 数据库层面回滚}catch(SQLExceptionex){thrownewTransactionSystemException(Could not roll back JDBC transaction,ex);}}3. Spring事务管理器核心设计思路设计点作用接口抽象PlatformTransactionManager解耦事务逻辑与具体数据库类型支持JDBC、JPA、Hibernate等线程绑定TransactionSynchronizationManager通过ThreadLocal存储当前线程的事务连接、事务状态保证同线程内方法共用连接传播行为处理支持REQUIRED、REQUIRES_NEW等传播行为灵活控制事务范围异常兼容封装数据库异常为Spring统一的TransactionException简化异常处理四、AOP事务管理器的完整执行流程Spring原生结合前面的分析梳理Spring中AOP实现事务的完整流程启动阶段EnableTransactionManagement开启事务注解驱动Spring扫描Transactional注解为目标类创建动态代理注册TransactionInterceptor事务拦截器实现MethodInterceptor。运行阶段Controller调用业务方法 → 代理对象拦截方法调用触发TransactionInterceptor.invoke()调用TransactionManager.getTransaction()开启事务TransactionManager获取连接关闭autoCommit执行原始业务方法业务执行成功 →TransactionManager.commit()提交事务业务执行异常 →TransactionManager.rollback()回滚事务释放连接恢复autoCommit返回结果给Controller。五、常见问题与核心注意点事务失效的核心原因方法非publicAOP无法拦截非public方法内部调用代理对象无法拦截如service.a()调用service.b()b()的事务失效线程池异步调用不同线程无法共享ThreadLocal中的连接异常被捕获未抛出到拦截器无法触发回滚。ThreadLocal的核心作用没有ThreadLocal不同方法会获取不同的数据库连接事务无法覆盖多个方法这是事务管理的核心。传播行为的本质传播行为是通过判断当前线程是否已有事务连接决定“新建连接”或“复用连接”。六、学习建议先运行手写版代码理解“注解AOP事务管理器ThreadLocal”的核心阅读Spring源码入口TransactionInterceptor.invoke()核心类DataSourceTransactionManager、TransactionSynchronizationManager调试事务失效场景如内部调用、异常捕获加深对代理和线程绑定的理解。总结Spring中AOP实现事务管理的核心流程可总结为首先通过EnableTransactionManagement开启事务注解驱动Spring扫描到业务方法上的Transactional注解后为目标业务类创建动态代理对象当调用方触发标注了Transactional的业务方法时实际调用的是代理对象的方法此时AOP的事务拦截器TransactionInterceptor会触发环绕通知逻辑——先调用事务管理器如DataSourceTransactionManager的getTransaction()方法从数据源获取连接并通过ThreadLocal绑定到当前线程关闭连接的自动提交以开启事务接着执行原始的业务方法逻辑若业务执行无异常事务管理器调用commit()提交事务若抛出符合回滚规则的异常则调用rollback()回滚事务最后无论提交或回滚都会释放数据库连接、恢复连接的自动提交状态并清空ThreadLocal中的事务信息整个过程通过AOP的代理和环绕通知将事务的开启、提交/回滚逻辑与业务代码解耦保证业务方法的原子性。