您的位置:首页 > 财经 > 金融 > 全国建筑企业查询平台_品牌设计有限公司_如何发布自己的html网站_在线识别图片来源

全国建筑企业查询平台_品牌设计有限公司_如何发布自己的html网站_在线识别图片来源

2025/4/24 1:43:53 来源:https://blog.csdn.net/AWen_Jack/article/details/146483067  浏览:    关键词:全国建筑企业查询平台_品牌设计有限公司_如何发布自己的html网站_在线识别图片来源
全国建筑企业查询平台_品牌设计有限公司_如何发布自己的html网站_在线识别图片来源

SpringBoot事务原理剖析

1. 事务管理核心接口体系

1.1 Spring事务抽象层次

Spring框架为事务管理提供了一套完整的抽象,使开发者能够以统一的方式处理不同环境下的事务操作。核心接口体系如下:

  • PlatformTransactionManager:事务管理器接口,定义事务的基本操作
  • TransactionDefinition:事务定义接口,封装事务的属性信息
  • TransactionStatus:事务状态接口,提供事务执行状态的操作方法
// org.springframework.transaction.PlatformTransactionManager (Spring 6.0)
public interface PlatformTransactionManager extends TransactionManager {// 根据事务定义创建一个新事务TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException;// 提交事务void commit(TransactionStatus status) throws TransactionException;// 回滚事务void rollback(TransactionStatus status) throws TransactionException;
}

1.2 关键实现类

SpringBoot中常用的事务管理器实现:

实现类适用场景特性
DataSourceTransactionManagerJDBC、MyBatis基于数据源连接的事务管理
JpaTransactionManagerJPA支持JPA EntityManager操作
HibernateTransactionManagerHibernate适用于Hibernate会话管理
JtaTransactionManager分布式事务支持JTA规范的事务管理

SpringBoot会根据classpath中检测到的持久化技术自动配置适合的事务管理器。

1.3 事务属性定义

TransactionDefinition接口定义了事务的关键属性:

// org.springframework.transaction.TransactionDefinition (Spring 6.0)
public interface TransactionDefinition {// 传播行为常量定义int PROPAGATION_REQUIRED = 0;int PROPAGATION_SUPPORTS = 1;int PROPAGATION_MANDATORY = 2;int PROPAGATION_REQUIRES_NEW = 3;// ... 其他传播行为常量// 隔离级别常量定义int ISOLATION_DEFAULT = -1;int ISOLATION_READ_UNCOMMITTED = 1;int ISOLATION_READ_COMMITTED = 2;int ISOLATION_REPEATABLE_READ = 4;int ISOLATION_SERIALIZABLE = 8;// 获取传播行为int getPropagationBehavior();// 获取隔离级别int getIsolationLevel();// 获取超时时间int getTimeout();// 是否只读事务boolean isReadOnly();// 获取事务名称@Nullable String getName();
}

2. 声明式事务实现原理

2.1 AOP代理机制

SpringBoot的声明式事务基于Spring AOP实现,本质是在目标方法执行前后进行事务操作的环绕增强。

// 简化的事务拦截器逻辑
public Object invoke(final MethodInvocation invocation) throws Throwable {// 获取事务属性TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);// 获取事务管理器PlatformTransactionManager tm = determineTransactionManager(txAttr);// 开启事务TransactionStatus status = tm.getTransaction(txAttr);try {// 执行目标方法Object retVal = invocation.proceed();// 提交事务tm.commit(status);return retVal;}catch (Throwable ex) {// 判断是否需要回滚if (txAttr.rollbackOn(ex)) {tm.rollback(status);} else {tm.commit(status);}throw ex;}
}

2.2 @Transactional注解解析

当在方法或类上使用@Transactional注解时,Spring会创建一个代理对象包装原始Bean:

  1. 注解解析:TransactionAttributeSource接口负责解析@Transactional注解
  2. 属性提取:提取传播行为、隔离级别等属性值
  3. 代理创建:根据Bean类型创建JDK动态代理或CGLIB代理
  4. 织入增强:将TransactionInterceptor织入目标方法执行链

2.3 事务执行流程

声明式事务的完整执行流程:

  1. 调用代理对象的方法
  2. 事务拦截器获取事务定义
  3. 通过事务管理器开启事务
  4. 执行目标方法业务逻辑
  5. 根据执行结果提交或回滚事务
  6. 释放事务资源

2.4 ThreadLocal在事务实现中的应用

Spring事务管理巧妙地利用了ThreadLocal机制来存储和传递事务上下文信息,这是实现声明式事务的关键技术之一。

2.4.1 TransactionSynchronizationManager核心实现

TransactionSynchronizationManager是Spring事务管理的核心工具类,它基于ThreadLocal存储当前线程的事务资源和同步器:

// org.springframework.transaction.support.TransactionSynchronizationManager (Spring 6.0)
public abstract class TransactionSynchronizationManager {// 存储当前线程的事务资源,key是资源标识,value是具体资源private static final ThreadLocal<Map<Object, Object>> resources = new NamedThreadLocal<>("Transactional resources");// 存储当前线程的事务同步器列表private static final ThreadLocal<Set<TransactionSynchronization>> synchronizations = new NamedThreadLocal<>("Transaction synchronizations");// 存储当前线程的事务名称private static final ThreadLocal<String> currentTransactionName = new NamedThreadLocal<>("Current transaction name");// 存储当前线程的事务只读状态private static final ThreadLocal<Boolean> currentTransactionReadOnly = new NamedThreadLocal<>("Current transaction read-only status");// 存储当前线程的事务隔离级别private static final ThreadLocal<Integer> currentTransactionIsolationLevel = new NamedThreadLocal<>("Current transaction isolation level");// 存储当前线程是否存在实际事务private static final ThreadLocal<Boolean> actualTransactionActive = new NamedThreadLocal<>("Actual transaction active");// 各种访问和操作ThreadLocal的方法...
}
2.4.2 ThreadLocal机制解决的问题
  1. 线程隔离:保证不同线程的事务上下文互不干扰,即使在多线程并发环境下
  2. 传播支持:事务上下文沿着同一线程的调用链自动传递,无需显式传参
  3. 资源绑定:将数据库连接等资源与当前线程绑定,确保事务中使用同一个物理连接
  4. 无侵入实现:业务代码无需感知事务管理的存在,实现了关注点分离
2.4.3 工作流程示例
执行@Transactional方法↓
TransactionInterceptor拦截↓
获取PlatformTransactionManager并开启事务↓
将数据库连接存入TransactionSynchronizationManager的resources ThreadLocal↓
设置相关事务属性到对应的ThreadLocal↓
执行业务方法(同一线程中的所有数据库操作都使用ThreadLocal中的同一连接)↓
根据执行结果提交或回滚事务↓
清理ThreadLocal中的事务资源
2.4.4 注意事项与陷阱
  1. 线程边界问题:ThreadLocal不能跨线程传递,因此在以下场景事务会失效:

    @Service
    public class AsyncService {@Autowiredprivate UserRepository userRepository;@Transactionalpublic void updateUserWithAsync(User user) {// 主线程事务userRepository.save(user);  // 开启新线程,ThreadLocal中的事务上下文无法传递到新线程!new Thread(() -> {// 新线程中没有事务上下文,这里的操作不在事务中userRepository.updateStatus(user.getId(), Status.PROCESSED);}).start();}
    }
    
  2. 线程池复用问题:由于线程池会复用线程,如果没有妥善清理ThreadLocal,可能导致事务上下文泄漏:

    // 一个常见的错误模式
    try {// 开启事务并在ThreadLocal中设置事务上下文txManager.begin();// 执行业务逻辑businessService.doSomething();txManager.commit();
    } catch (Exception e) {txManager.rollback();throw e;
    }
    // 缺少finally块清理ThreadLocal,如果发生异常可能导致ThreadLocal中残留事务上下文
    
  3. @Async方法的事务问题:Spring的@Async会使用不同的线程执行方法,导致事务上下文丢失:

    @Service
    public class UserService {@Transactionalpublic void updateUser(User user) {// 主事务repository.save(user);// @Async方法在新线程中执行,无法获取到当前线程的事务上下文asyncService.sendNotification(user.getId());}
    }@Service
    public class AsyncService {@Async@Transactional // 这是一个独立的事务,与调用方事务无关public void sendNotification(Long userId) {// ...}
    }
    

3. 事务传播行为详解

3.1 核心传播行为矩阵

传播行为决定了事务方法和已存在事务之间的关系:

传播行为外部无事务外部有事务应用场景
REQUIRED (默认)创建新事务加入已有事务大多数业务方法
REQUIRES_NEW创建新事务挂起外部事务,创建新事务独立记录日志、发送消息
SUPPORTS无事务执行加入已有事务查询方法
NOT_SUPPORTED无事务执行挂起外部事务,无事务执行耗时操作
MANDATORY抛出异常加入已有事务强制要求外部调用必须有事务
NEVER无事务执行抛出异常禁止在事务中执行
NESTED创建新事务创建嵌套事务(通过保存点)子操作有独立的回滚点

3.2 传播行为决策树

                  ┌── 有外部事务 ──► 加入外部事务
REQUIRED ──────┤└── 无外部事务 ──► 创建新事务┌── 有外部事务 ──► 挂起外部事务,创建新事务
REQUIRES_NEW ──┤└── 无外部事务 ──► 创建新事务┌── 有外部事务 ──► 创建保存点嵌套事务
NESTED ────────┤└── 无外部事务 ──► 创建新事务

3.3 常见事务失效场景

  1. 自调用问题

    @Service
    public class UserService {@Transactionalpublic void updateUser(User user) {// 事务生效}public void doSomething() {updateUser(new User()); // 事务失效!实际是this.updateUser(),没有通过代理}
    }
    
  2. 方法非public

    @Service
    public class UserService {@Transactionalprotected void updateUser(User user) { // 事务失效,方法必须是public// ...}
    }
    
  3. 异常被吞没

    @Transactional
    public void updateUser(User user) {try {// 数据库操作} catch (Exception e) {log.error("更新失败", e);// 异常被捕获但未抛出,事务不会回滚}
    }
    
  4. 异常类型不匹配

    @Transactional // 默认只回滚RuntimeException和Error
    public void updateUser(User user) throws SQLException {// 如果抛出SQLException,事务不会回滚
    }// 正确用法
    @Transactional(rollbackFor = SQLException.class)
    public void updateUser(User user) throws SQLException {// 现在SQLException也会触发回滚
    }
    

3.4 使用ThreadLocal实现事务传播机制

事务传播行为的底层实现依赖于ThreadLocal存储的事务上下文信息:

// AbstractPlatformTransactionManager伪代码展示
protected TransactionStatus handleExistingTransaction(TransactionDefinition definition, Object transaction, boolean debugEnabled)throws TransactionException {// 获取当前线程ThreadLocal中已存在的事务if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {// NEVER: 存在事务则抛出异常throw new IllegalTransactionStateException("已存在事务");}if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {// NOT_SUPPORTED: 挂起当前事务并清除ThreadLocal中的事务资源Object suspendedResources = suspend(transaction);// 创建一个无事务的执行环境return newTransactionStatus(...);}if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {// REQUIRES_NEW: 挂起当前事务的ThreadLocal资源,创建新事务并存入ThreadLocalObject suspendedResources = suspend(transaction);try {// 创建新事务并绑定到当前线程的ThreadLocalreturn startTransaction(...);}catch (RuntimeException | Error ex) {// 恢复之前挂起的事务资源到ThreadLocalresume(transaction, suspendedResources);throw ex;}}if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {// NESTED: 使用保存点在同一事务中创建嵌套事务// ...}// REQUIRED/SUPPORTS/MANDATORY: 加入现有事务// 使用ThreadLocal中已有的事务资源return new TransactionStatus(...);
}

4. 实战应用指南

4.1 事务配置最佳实践

@Service
public class OrderService {@Autowiredprivate OrderRepository orderRepository;@Autowiredprivate PaymentService paymentService;// 完整配置示例@Transactional(propagation = Propagation.REQUIRED,      // 传播行为isolation = Isolation.READ_COMMITTED,    // 隔离级别timeout = 30,                            // 超时时间(秒)readOnly = false,                        // 是否只读rollbackFor = Exception.class            // 触发回滚的异常)public void createOrder(Order order) {// 创建订单orderRepository.save(order);// 处理支付paymentService.processPayment(order);}// 只读事务示例@Transactional(readOnly = true)public List<Order> getUserOrders(Long userId) {return orderRepository.findByUserId(userId);}
}

4.2 编程式事务示例

除了声明式事务,Spring还支持编程式事务管理:

@Service
public class ManualTransactionService {@Autowiredprivate PlatformTransactionManager transactionManager;public void complexOperation() {// 定义事务属性DefaultTransactionDefinition def = new DefaultTransactionDefinition();def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);def.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);def.setTimeout(30);// 开启事务TransactionStatus status = transactionManager.getTransaction(def);try {// 执行业务逻辑// ...// 提交事务transactionManager.commit(status);} catch (Exception e) {// 回滚事务transactionManager.rollback(status);throw e;}}
}

4.3 事务边界设计

在设计事务边界时应考虑以下因素:

  1. 原子性要求:将逻辑上必须一起成功或失败的操作放在同一事务中
  2. 性能影响:事务过大会增加锁争用,过小则无法保证数据一致性
  3. 超时控制:为长事务设置合理的超时时间
  4. 异常处理:明确定义哪些异常应触发回滚
  5. 嵌套调用:理解传播行为对事务嵌套的影响

5. 事务监控与排错

5.1 事务日志配置

开启Spring事务相关日志:

# application.properties
logging.level.org.springframework.transaction=DEBUG
logging.level.org.springframework.orm.jpa=DEBUG
logging.level.org.hibernate.SQL=DEBUG

5.2 事务状态排查工具

工具/方法用途适用场景
TransactionSynchronizationManager检查当前线程事务状态调试
DataSource代理监控执行的SQL开发测试
数据库监控检查锁和事务性能分析
Spring Boot Actuator事务统计生产监控

5.3 常见问题解决方案

  1. 事务不回滚

    • 检查异常类型是否符合回滚条件
    • 确认是否通过代理对象调用
    • 检查是否有嵌套事务配置错误
  2. 死锁问题

    • 合理设置隔离级别
    • 控制事务大小和执行时间
    • 优化操作顺序避免循环等待
  3. 长事务处理

    • 使用补偿事务替代长事务
    • 实现分段提交
    • 设计幂等操作支持重试

5.4 ThreadLocal相关的事务问题排查

开发中常见的与ThreadLocal相关的事务问题及解决方案:

5.4.1 检查事务上下文是否激活

使用TransactionSynchronizationManager工具类检查当前线程是否存在活跃事务:

// 在可疑的方法中添加调试代码
boolean hasActiveTransaction = TransactionSynchronizationManager.isActualTransactionActive();
String txName = TransactionSynchronizationManager.getCurrentTransactionName();
log.debug("当前线程[{}]是否有事务:{},事务名称:{}", Thread.currentThread().getName(), hasActiveTransaction, txName);
5.4.2 多线程环境事务传播方案

在需要跨线程传播事务上下文的场景,可以考虑以下方案:

  1. 编程式事务+手动传参:不依赖ThreadLocal自动传播,显式传递事务所需参数

    // 主方法
    public void processOrder(Order order) {transactionTemplate.execute(status -> {// 获取当前连接Connection connection = DataSourceUtils.getConnection(dataSource);// 传递给异步方法asyncProcess(order, connection);return null;});
    }// 异步方法
    public void asyncProcess(Order order, Connection sharedConnection) {// 使用传入的共享连接// ...
    }
    
  2. 使用TransactionSynchronizationManager暂存资源

    @Transactional
    public void complexProcess() {// 主事务操作repository.save(entity);// 获取当前事务的关键资源,如数据源和连接DataSource dataSource = TransactionSynchronizationManager.getResource(dataSource);// 注册事务同步器,在事务完成后执行清理TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {@Overridepublic void afterCompletion(int status) {// 清理资源}});
    }
    
5.4.3 Spring事务上下文监控工具

对于复杂的事务问题,可以实现一个简单的监控工具追踪ThreadLocal事务上下文:

@Aspect
@Component
public class TransactionContextMonitor {private static final Logger log = LoggerFactory.getLogger(TransactionContextMonitor.class);@Around("@annotation(org.springframework.transaction.annotation.Transactional)")public Object monitorTransactionContext(ProceedingJoinPoint pjp) throws Throwable {String methodName = pjp.getSignature().toShortString();Thread currentThread = Thread.currentThread();log.info("方法[{}]在线程[{}]开始执行,事务活跃状态: {}", methodName, currentThread.getName(),TransactionSynchronizationManager.isActualTransactionActive());// 记录事务资源Map<Object, Object> resourceMap = TransactionSynchronizationManager.getResourceMap();log.info("事务资源: {}", resourceMap.keySet());try {return pjp.proceed();} finally {log.info("方法[{}]在线程[{}]执行结束,事务活跃状态: {}", methodName, currentThread.getName(),TransactionSynchronizationManager.isActualTransactionActive());}}
}

总结

SpringBoot事务管理机制构建在Spring事务抽象之上,通过AOP实现声明式事务管理。开发者需理解事务传播行为、隔离级别以及常见的事务失效场景,才能设计出健壮的事务解决方案。

在实际应用中,应根据业务特点选择合适的事务传播行为和隔离级别,避免过大的事务边界,并为关键业务操作编写完善的单元测试验证事务行为。

SpringBoot事务管理广泛使用ThreadLocal机制实现线程隔离和事务上下文传播,这使得声明式事务能够优雅地工作,但也带来了多线程环境下的特殊考虑。理解ThreadLocal在事务中的应用,有助于更好地设计事务边界和排查复杂的事务问题。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com