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

Spring面试题及详细答案 125道(46-65) -- 事务管理

前后端面试题》专栏集合了前后端各个知识模块的面试题,包括html,javascript,css,vue,react,java,Openlayers,leaflet,cesium,mapboxGL,threejs,nodejs,mangoDB,SQL,Linux… 。

前后端面试题-专栏总目录

在这里插入图片描述

文章目录

  • 一、本文面试题目录
      • 46. Spring事务管理的核心接口有哪些?
      • 47. 什么是声明式事务?什么是编程式事务?各有什么优缺点?
      • 48. Spring事务的传播行为有哪些?请解释各自的含义。
      • 49. Spring事务的隔离级别有哪些?和数据库的隔离级别有什么关系?
      • 50. 如何在Spring中配置声明式事务?(基于XML和注解)
      • 51. @Transactional注解的常用属性有哪些?
      • 52. 什么情况下Spring事务会失效?
      • 53. 如何实现分布式事务?Spring对分布式事务有哪些支持?
      • 54. 请解释事务的ACID特性。
      • 55. 什么是脏读、不可重复读、幻读?如何通过隔离级别避免?
      • 56. Spring事务管理中,如何指定事务的回滚规则?
        • 原理说明:
        • 示例代码:
      • 57. 只读事务的作用是什么?
        • 原理说明:
        • 示例代码:
        • 注意:
      • 58. 嵌套事务和事务传播行为中的NESTED有什么关系?
        • 关系说明:
        • 示例代码:
      • 59. 如何在Spring中使用编程式事务?
        • 原理说明:
        • 示例代码:
      • 60. Spring事务同步机制是什么?
        • 原理说明:
        • 示例代码:
        • 应用场景:
      • 61. @Transactional注解的 propagation=REQUIRES_NEW 和 NESTED 有什么区别?
        • 示例代码:
      • 62. 为什么说事务的隔离级别越高,性能可能越低?
        • 原因分析:
        • 总结:
      • 63. 如何在Spring中实现事务的手动回滚?
        • 实现方式:
      • 64. 多线程环境下,Spring事务会出现什么问题?如何解决?
        • 问题说明:
        • 解决方式:
      • 65. 什么是事务的超时时间?如何配置?
        • 配置方式:
        • 注意:

一、本文面试题目录

46. Spring事务管理的核心接口有哪些?

Spring事务管理的核心接口如下:

  • PlatformTransactionManager(平台事务管理器)
    事务管理的核心接口,定义了事务的基本操作(获取、提交、回滚),不同的数据源(如JDBC、Hibernate)有不同实现:

    • DataSourceTransactionManager:用于JDBC或MyBatis的事务管理。
    • HibernateTransactionManager:用于Hibernate的事务管理。
    • JpaTransactionManager:用于JPA的事务管理。
      核心方法:
    TransactionStatus getTransaction(TransactionDefinition definition); // 获取事务
    void commit(TransactionStatus status); // 提交事务
    void rollback(TransactionStatus status); // 回滚事务
    
  • TransactionDefinition(事务定义)
    定义事务的属性(隔离级别、传播行为、超时时间、是否只读),常用实现类为DefaultTransactionDefinition

  • TransactionStatus(事务状态)
    代表当前事务的运行状态,提供事务是否活跃、是否已提交、是否需要回滚等信息。

47. 什么是声明式事务?什么是编程式事务?各有什么优缺点?

  • 声明式事务
    通过注解(如@Transactional)或XML配置声明事务规则,无需手动编写事务控制代码,由Spring自动管理事务。

    • 优点
      • 非侵入式,业务代码与事务逻辑分离,代码简洁。
      • 配置灵活,便于统一管理和修改。
    • 缺点
      • 细粒度控制能力较弱(如部分代码需要事务,部分不需要)。
      • 异常处理依赖默认规则,自定义回滚逻辑较复杂。
    • 示例
      @Service
      public class OrderService {@Transactional // 声明式事务public void createOrder() {// 业务逻辑(自动纳入事务管理)}
      }
      
  • 编程式事务
    通过手动编写代码控制事务(如TransactionTemplatePlatformTransactionManager),显式定义事务的开始、提交和回滚。

    • 优点
      • 细粒度控制,可精确控制事务范围(如条件性提交/回滚)。
      • 灵活度高,支持复杂的事务逻辑。
    • 缺点
      • 侵入业务代码,事务逻辑与业务逻辑混杂。
      • 代码冗余,重复编写事务控制代码。
    • 示例
      @Service
      public class OrderService {@Autowiredprivate TransactionTemplate transactionTemplate;public void createOrder() {transactionTemplate.execute(status -> { // 编程式事务try {// 业务逻辑return true;} catch (Exception e) {status.setRollbackOnly(); // 手动回滚return false;}});}
      }
      

48. Spring事务的传播行为有哪些?请解释各自的含义。

事务传播行为定义了多个事务方法相互调用时,事务的传播规则。Spring定义了7种传播行为:

  • PROPAGATION_REQUIRED(默认)
    如果当前存在事务,则加入该事务;如果没有事务,则创建新事务。

    @Transactional(propagation = Propagation.REQUIRED)
    public void methodA() { methodB(); } // methodA和methodB在同一事务中@Transactional(propagation = Propagation.REQUIRED)
    public void methodB() {}
    
  • PROPAGATION_SUPPORTS
    如果当前存在事务,则加入该事务;如果没有事务,则以非事务方式执行。

  • PROPAGATION_MANDATORY
    必须在已存在的事务中执行,否则抛出IllegalTransactionStateException

  • PROPAGATION_REQUIRES_NEW
    无论当前是否存在事务,都创建新事务(原事务暂停,新事务执行完毕后恢复原事务)。

    @Transactional(propagation = Propagation.REQUIRED)
    public void methodA() { methodB(); } // methodA的事务与methodB的事务独立@Transactional(propagation = Propagation.REQUIRES_NEW)
    public void methodB() {}
    
  • PROPAGATION_NOT_SUPPORTED
    以非事务方式执行,如果当前存在事务,则暂停该事务。

  • PROPAGATION_NEVER
    以非事务方式执行,如果当前存在事务,则抛出异常。

  • PROPAGATION_NESTED
    如果当前存在事务,则在嵌套事务中执行(嵌套事务依赖于外层事务,外层回滚则嵌套事务也回滚);如果没有事务,则创建新事务。

49. Spring事务的隔离级别有哪些?和数据库的隔离级别有什么关系?

  • Spring事务的隔离级别(定义在Isolation枚举中):

    1. DEFAULT(默认):使用数据库默认的隔离级别(如MySQL默认REPEATABLE_READ,Oracle默认READ_COMMITTED)。
    2. READ_UNCOMMITTED:允许读取未提交的数据(可能导致脏读、不可重复读、幻读)。
    3. READ_COMMITTED:只能读取已提交的数据(避免脏读,可能导致不可重复读、幻读)。
    4. REPEATABLE_READ:保证多次读取同一数据结果一致(避免脏读、不可重复读,可能导致幻读)。
    5. SERIALIZABLE:最高隔离级别,完全避免并发问题(但性能极低)。
  • 与数据库隔离级别的关系

    • Spring的隔离级别是对数据库隔离级别的封装,最终由数据库实现(Spring不直接提供隔离能力)。
    • 若Spring配置的隔离级别数据库不支持,会抛出异常(如MySQL不支持SERIALIZABLE时强制使用会报错)。
    • 示例(指定隔离级别):
      @Transactional(isolation = Isolation.READ_COMMITTED)
      public void queryData() {// 事务隔离级别为READ_COMMITTED
      }
      

50. 如何在Spring中配置声明式事务?(基于XML和注解)

  • 方式1:基于注解配置

    1. 启用事务注解支持:
      @Configuration
      @EnableTransactionManagement // 启用声明式事务
      public class TxConfig {// 配置数据源@Beanpublic DataSource dataSource() {// 数据源配置(如HikariCP)}// 配置事务管理器@Beanpublic PlatformTransactionManager transactionManager(DataSource dataSource) {return new DataSourceTransactionManager(dataSource);}
      }
      
    2. 在业务方法上添加@Transactional
      @Service
      public class UserService {@Transactional // 该方法纳入事务管理public void updateUser(Long id, String name) {// 数据库操作}
      }
      
  • 方式2:基于XML配置

    <!-- 配置数据源 -->
    <bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource"><property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"/><property name="username" value="root"/><property name="password" value="123456"/>
    </bean><!-- 配置事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/>
    </bean><!-- 配置事务通知 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager"><tx:attributes><tx:method name="add*" propagation="REQUIRED"/> <!-- 匹配add开头的方法 --><tx:method name="update*" propagation="REQUIRED"/><tx:method name="*" read-only="true"/> <!-- 其他方法只读 --></tx:attributes>
    </tx:advice><!-- 配置AOP切入点 -->
    <aop:config><aop:pointcut id="txPointcut" expression="execution(* com.example.service.*.*(..))"/><aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
    </aop:config>
    

51. @Transactional注解的常用属性有哪些?

@Transactional注解的常用属性如下:

  • propagation:事务传播行为(默认REQUIRED),如propagation = Propagation.REQUIRES_NEW
  • isolation:事务隔离级别(默认DEFAULT),如isolation = Isolation.READ_COMMITTED
  • readOnly:是否为只读事务(默认false),查询操作可设为true提升性能:
    @Transactional(readOnly = true)
    public List<User> queryUsers() { ... }
    
  • timeout:事务超时时间(单位:秒,默认-1表示无超时),超时后自动回滚:
    @Transactional(timeout = 30) // 30秒超时
    public void longRunningTask() { ... }
    
  • rollbackFor:指定触发回滚的异常类型(默认仅回滚RuntimeException及其子类):
    @Transactional(rollbackFor = {SQLException.class, IOException.class})
    public void saveData() { ... }
    
  • noRollbackFor:指定不触发回滚的异常类型:
    @Transactional(noRollbackFor = BusinessException.class)
    public void process() { ... }
    
  • value/transactionManager:指定事务管理器(多数据源时使用)。

52. 什么情况下Spring事务会失效?

Spring事务失效的常见场景如下:

  • 1. 方法未被Spring管理
    若类未被@Service@Component等注解标记(未纳入Spring容器),@Transactional无效。

    // 错误:未被Spring管理
    public class UserService {@Transactionalpublic void update() { ... }
    }
    
  • 2. 方法不是public
    @Transactional仅对public方法生效(非public方法的注解会被忽略)。

    @Service
    public class UserService {@Transactionalprivate void update() { ... } // 私有方法,事务失效
    }
    
  • 3. 自身调用(未通过代理对象)
    同一类中方法A调用方法B,若B有@Transactional而A没有,B的事务失效(因未经过代理)。

    @Service
    public class UserService {public void methodA() {methodB(); // 自身调用,methodB的事务失效}@Transactionalpublic void methodB() { ... }
    }
    
  • 4. 异常被捕获且未重新抛出
    若方法内捕获异常且未抛出,Spring无法感知异常,不会触发回滚。

    @Transactional
    public void update() {try {// 数据库操作} catch (Exception e) {// 错误:未抛出异常,事务不回滚}
    }
    
  • 5. 异常类型不匹配
    默认仅回滚RuntimeException,若抛出检查型异常(如IOException)且未指定rollbackFor,事务不回滚。

    @Transactional // 未指定rollbackFor,下面的异常不会触发回滚
    public void update() throws IOException {throw new IOException();
    }
    
  • 6. 错误的传播行为
    如使用PROPAGATION_NOT_SUPPORTED(非事务方式执行)会导致事务失效。

53. 如何实现分布式事务?Spring对分布式事务有哪些支持?

分布式事务是指跨多个数据库或服务的事务,需保证ACID特性。常见实现方案及Spring支持如下:

  • 1. 2PC(两阶段提交)

    • 原理:分准备阶段(所有参与者确认可提交)和提交阶段(协调者通知所有参与者提交)。
    • Spring支持:通过JtaTransactionManager整合JTA(Java Transaction API),适配支持JTA的容器(如JBoss)或分布式事务管理器(如Atomikos)。
    @Bean
    public PlatformTransactionManager transactionManager() {return new JtaTransactionManager(); // 基于JTA的分布式事务管理器
    }
    
  • 2. TCC(Try-Confirm-Cancel)

    • 原理:自定义三个阶段(尝试资源检查与预留、确认操作、取消操作),业务侵入性强但性能好。
    • Spring支持:无原生支持,需结合中间件(如Seata)实现。
    // TCC示例接口
    public interface OrderTccService {void tryCreate(Order order); // 尝试创建订单(预留库存)void confirmCreate(Order order); // 确认创建void cancelCreate(Order order); // 取消创建(释放库存)
    }
    
  • 3. SAGA模式

    • 原理:将分布式事务拆分为本地事务序列,通过补偿事务回滚。
    • Spring支持:可通过Spring StateMachine实现状态流转,或结合Seata、Hmily等框架。
  • 4. 本地消息表

    • 原理:通过本地事务记录消息,异步通知其他服务,最终一致性方案。
    • Spring支持:结合Spring事务和消息队列(如RabbitMQ)实现。
  • Spring Cloud相关支持

    • Spring Cloud Alibaba Seata:提供AT(自动补偿)、TCC等模式的分布式事务支持。
    • Spring Cloud Stream:结合消息队列实现最终一致性事务。

54. 请解释事务的ACID特性。

事务的ACID特性是保证数据一致性的四大核心原则:

  • 原子性(Atomicity)
    事务是不可分割的最小单元,要么全部执行成功,要么全部失败回滚,不存在部分执行的情况。
    例如:转账操作中,“A账户扣款”和“B账户收款”必须同时成功或同时失败。

  • 一致性(Consistency)
    事务执行前后,数据从一个合法状态转换为另一个合法状态,满足业务规则约束。
    例如:转账前后,A和B的账户总金额保持不变。

  • 隔离性(Isolation)
    多个并发事务之间相互隔离,一个事务的执行不应被其他事务干扰,避免并发问题(脏读、不可重复读、幻读)。
    数据库通过锁机制和MVCC(多版本并发控制)实现隔离性。

  • 持久性(Durability)
    事务一旦提交,其修改会永久保存到数据库中,即使系统崩溃也不会丢失。
    数据库通过日志(如redo log)实现持久性,确保提交的数据可恢复。

55. 什么是脏读、不可重复读、幻读?如何通过隔离级别避免?

  • 脏读(Dirty Read)
    一个事务读取到另一个未提交事务修改的数据。

    • 示例:事务A修改了数据但未提交,事务B读取到该数据,随后事务A回滚,事务B读取的数据为“脏数据”。
    • 避免方式:隔离级别设为READ_COMMITTED及以上。
  • 不可重复读(Non-Repeatable Read)
    同一事务内,多次读取同一数据时,结果不一致(因其他事务修改并提交了该数据)。

    • 示例:事务A第一次读取数据为100,事务B修改数据为200并提交,事务A再次读取数据为200。
    • 避免方式:隔离级别设为REPEATABLE_READ及以上。
  • 幻读(Phantom Read)
    同一事务内,多次执行相同查询时,结果集行数不一致(因其他事务插入或删除了数据)。

    • 示例:事务A查询年龄>20的用户有3人,事务B插入1个年龄>20的用户并提交,事务A再次查询发现有4人。
    • 避免方式:隔离级别设为SERIALIZABLE(最高级别,通过全表锁避免幻读)。
  • 隔离级别与并发问题的关系

    隔离级别脏读不可重复读幻读
    READ_UNCOMMITTED可能可能可能
    READ_COMMITTED避免可能可能
    REPEATABLE_READ避免避免可能
    SERIALIZABLE避免避免避免

56. Spring事务管理中,如何指定事务的回滚规则?

Spring事务默认会对所有未检查异常(RuntimeException及其子类)Error进行回滚,对已检查异常(如IOException、SQLException等) 不回滚。若需自定义回滚规则,可通过以下方式实现:

原理说明:
  • 通过@Transactional注解的rollbackFornoRollbackFor属性指定回滚或不回滚的异常类型。
  • rollbackFor:指定需要回滚的异常(即使是已检查异常)。
  • noRollbackFor:指定不需要回滚的异常(即使是未检查异常)。
示例代码:
@Service
public class UserService {// 对NullPointerException和IOException回滚,对ArithmeticException不回滚@Transactional(rollbackFor = {NullPointerException.class, IOException.class}, noRollbackFor = ArithmeticException.class)public void updateUser() throws IOException {// 业务逻辑if (true) {throw new IOException("IO异常,触发回滚");}if (true) {throw new ArithmeticException("算术异常,不回滚");}}
}

57. 只读事务的作用是什么?

只读事务是指事务执行过程中不修改数据,仅进行查询操作。其作用主要体现在性能优化和数据库约束上。

原理说明:
  • 性能优化:数据库可针对只读事务进行优化(如避免加写锁、减少日志记录等),尤其在批量查询场景下提升效率。
  • 约束提示:明确告知数据库和Spring该事务无写操作,数据库可能拒绝在只读事务中执行更新语句(如MySQL的InnoDB引擎)。
示例代码:
@Service
public class UserService {// 标记为只读事务@Transactional(readOnly = true)public List<User> queryAllUsers() {// 仅查询操作,无更新return userDao.findAll();}
}
注意:
  • 若在只读事务中执行更新操作,可能抛出异常(如SQLException: Connection is read-only)。
  • 只读事务仅对REQUIREDREQUIRES_NEW等传播行为有效。

58. 嵌套事务和事务传播行为中的NESTED有什么关系?

  • 嵌套事务:是一种事务嵌套机制,外层事务中可以包含内层事务,内层事务依赖外层事务,外层事务回滚时内层事务也会回滚,但内层事务回滚不影响外层事务(除非手动设置)。
  • NESTED传播行为:Spring通过propagation = Propagation.NESTED支持嵌套事务,其底层依赖数据库的保存点(Savepoint) 机制。
关系说明:
  • NESTED是Spring实现嵌套事务的方式之一,外层事务会为内层事务创建保存点。
  • 内层事务回滚时,仅回滚到保存点,不影响外层事务的后续操作;外层事务回滚时,所有内层事务均回滚。
示例代码:
@Service
public class OrderService {@Autowiredprivate PaymentService paymentService;@Transactional(propagation = Propagation.REQUIRED)public void createOrder() {// 外层事务逻辑(如创建订单)try {paymentService.pay(); // 调用内层NESTED事务} catch (Exception e) {// 内层事务回滚,外层事务可继续执行System.out.println("支付失败,订单仍可继续处理");}}
}@Service
public class PaymentService {// 内层嵌套事务@Transactional(propagation = Propagation.NESTED)public void pay() {// 支付逻辑,若失败则回滚到保存点throw new RuntimeException("支付失败");}
}

59. 如何在Spring中使用编程式事务?

编程式事务是通过手动编写代码控制事务的开始、提交和回滚,适用于需要细粒度控制事务的场景。Spring中可通过PlatformTransactionManagerTransactionTemplate实现。

原理说明:
  • PlatformTransactionManager:事务管理器核心接口,定义了getTransaction()(获取事务)、commit()(提交)、rollback()(回滚)方法。
  • TransactionTemplate:模板类,简化编程式事务代码,通过execute()方法封装事务逻辑。
示例代码:
@Service
public class ProductService {@Autowiredprivate PlatformTransactionManager transactionManager;@Autowiredprivate ProductDao productDao;// 方式1:使用PlatformTransactionManager手动控制public void updateProduct1() {// 定义事务属性DefaultTransactionDefinition def = new DefaultTransactionDefinition();def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);// 获取事务状态TransactionStatus status = transactionManager.getTransaction(def);try {// 业务逻辑productDao.updateStock();transactionManager.commit(status); // 提交事务} catch (Exception e) {transactionManager.rollback(status); // 回滚事务throw e;}}// 方式2:使用TransactionTemplate(推荐)public void updateProduct2() {TransactionTemplate template = new TransactionTemplate(transactionManager);template.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);template.execute(status -> {try {// 业务逻辑productDao.updateStock();return null;} catch (Exception e) {status.setRollbackOnly(); // 标记回滚throw e;}});}
}

60. Spring事务同步机制是什么?

Spring事务同步机制是指在事务生命周期的特定阶段(如提交后、回滚后) 执行自定义逻辑的机制,通过TransactionSynchronization接口实现。

原理说明:
  • 当事务启动后,可注册TransactionSynchronization实例到TransactionSynchronizationManager中。
  • 事务执行到不同阶段(如beforeCommitafterCommitafterRollback等)时,Spring会回调同步器的对应方法。
示例代码:
@Service
public class OrderService {@Transactionalpublic void createOrder() {// 注册事务同步器TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {@Overridepublic void beforeCommit(boolean readOnly) {System.out.println("事务提交前执行(如数据校验)");}@Overridepublic void afterCommit() {System.out.println("事务提交后执行(如发送消息通知)");}@Overridepublic void afterRollback() {System.out.println("事务回滚后执行(如日志记录)");}});// 业务逻辑:创建订单orderDao.insert();}
}
应用场景:
  • 事务提交后发送消息、更新缓存。
  • 事务回滚后记录审计日志。

61. @Transactional注解的 propagation=REQUIRES_NEW 和 NESTED 有什么区别?

特性REQUIRES_NEWNESTED
事务独立性开启全新事务,与外层事务完全独立依赖外层事务,内层事务是外层的一部分
回滚影响内层事务回滚不影响外层,外层回滚不影响内层内层回滚不影响外层,外层回滚会带动内层回滚
底层实现依赖事务管理器创建新事务依赖数据库保存点(Savepoint)
适用场景日志记录、独立操作(如扣积分)嵌套业务(如订单创建包含支付)
示例代码:
@Service
public class OrderService {@Autowiredprivate PaymentService paymentService;// 外层事务@Transactional(propagation = Propagation.REQUIRED)public void createOrder() {System.out.println("创建订单");try {// 调用REQUIRES_NEW的内层事务paymentService.payWithRequiresNew();// 调用NESTED的内层事务paymentService.payWithNested();} catch (Exception e) {// 外层事务回滚时:// - REQUIRES_NEW的内层事务已独立提交,不受影响// - NESTED的内层事务会随外层回滚}}
}@Service
public class PaymentService {// REQUIRES_NEW:创建新事务@Transactional(propagation = Propagation.REQUIRES_NEW)public void payWithRequiresNew() {System.out.println("执行支付(REQUIRES_NEW)");}// NESTED:嵌套事务@Transactional(propagation = Propagation.NESTED)public void payWithNested() {System.out.println("执行支付(NESTED)");}
}

62. 为什么说事务的隔离级别越高,性能可能越低?

事务隔离级别定义了多个并发事务之间的可见性规则,隔离级别越高,数据一致性越强,但需要更多的锁机制或资源开销,导致性能下降。

原因分析:
  • 读未提交(READ_UNCOMMITTED):几乎无锁,性能最高,但可能出现脏读。
  • 读已提交(READ_COMMITTED):通过行级锁避免脏读,但需频繁加锁/解锁,性能中等。
  • 可重复读(REPEATABLE_READ):通过间隙锁(如MySQL InnoDB)避免不可重复读和幻读,锁范围扩大,性能下降。
  • 串行化(SERIALIZABLE):最高隔离级别,通过表级锁强制事务串行执行,并发能力极差,性能最低。
总结:

隔离级别升高 → 锁机制更复杂(锁范围更大、持有时间更长) → 并发冲突增加 → 性能降低。实际开发中需在一致性和性能间权衡(如多数场景使用READ_COMMITTED)。

63. 如何在Spring中实现事务的手动回滚?

Spring支持通过编程方式手动触发事务回滚,适用于需要根据业务逻辑判断是否回滚的场景。

实现方式:
  1. 通过TransactionStatus手动回滚(编程式事务):

    @Service
    public class UserService {@Autowiredprivate PlatformTransactionManager transactionManager;public void updateUser() {TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());try {// 业务逻辑if (/* 满足回滚条件 */) {transactionManager.rollback(status); // 手动回滚return;}transactionManager.commit(status);} catch (Exception e) {transactionManager.rollback(status);}}
    }
    
  2. 通过TransactionAspectSupport回滚(声明式事务):

    @Service
    public class UserService {@Transactionalpublic void updateUser() {try {// 业务逻辑if (/* 满足回滚条件 */) {// 手动触发回滚TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();return;}} catch (Exception e) {// 自动回滚或手动增强TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();}}
    }
    

64. 多线程环境下,Spring事务会出现什么问题?如何解决?

问题说明:

Spring事务基于线程绑定(通过ThreadLocal实现),多线程环境下,子线程无法继承父线程的事务上下文,可能导致:

  • 子线程的操作脱离父线程事务,无法一起提交或回滚。
  • 事务资源(如数据库连接)在多线程间共享时出现并发问题。
解决方式:
  1. 避免在事务中开启子线程:将多线程逻辑移到事务外,通过分布式事务或消息队列保证一致性。
  2. 手动传递事务上下文(不推荐,复杂度高):
    @Service
    public class OrderService {@Transactionalpublic void createOrder() {// 获取当前事务上下文TransactionStatus status = TransactionAspectSupport.currentTransactionStatus();// 子线程中手动绑定上下文(需自定义事务管理器支持)new Thread(() -> {TransactionSynchronizationManager.bindResource(dataSource, status.getConnectionHolder());try {// 子线程业务逻辑} finally {TransactionSynchronizationManager.unbindResource(dataSource);}}).start();}
    }
    
  3. 使用分布式事务框架(如Seata):适用于跨服务多线程场景。

65. 什么是事务的超时时间?如何配置?

事务的超时时间是指事务从开始到提交的最大允许时间,若超过该时间未提交,事务会自动回滚,避免长期占用资源。

配置方式:
  1. 通过@Transactional注解的timeout属性(单位:秒,默认-1表示不超时):

    @Service
    public class OrderService {// 事务超时时间设置为5秒@Transactional(timeout = 5)public void createOrder() {// 业务逻辑(若执行超过5秒,自动回滚)try {Thread.sleep(6000); // 模拟超时} catch (InterruptedException e) {e.printStackTrace();}}
    }
    
  2. XML配置方式

    <tx:advice id="txAdvice" transaction-manager="transactionManager"><tx:attributes><tx:method name="create*" timeout="5"/> <!-- 超时5秒 --></tx:attributes>
    </tx:advice>
    
注意:
  • 超时时间从事务开始(获取数据库连接)到提交前的总时间,不包括提交过程本身。
  • 底层依赖数据库支持(如MySQL的innodb_lock_wait_timeout可能影响实际超时行为)。
http://www.dtcms.com/a/390293.html

相关文章:

  • OA ⇄ CRM 单点登录(SSO)实现说明
  • 人工智能在设备管理软件中的应用
  • __pycache__ 文件夹作用
  • 利欧泵业数据中心液冷系统解决方案亮相2025 ODCC开放数据中心峰会
  • 【论文阅读】Masked Conditional Variational Autoencoders for Chromosome Straightening
  • 天气预测:AI 如何为我们 “算” 出未来的天空?
  • 大数据管理与应用有什么注意事项?企业该如何发挥大数据的价值
  • CSS的opacity 属性
  • STM32 LwIP协议栈优化:从TCP延迟10ms降至1ms的内存配置手册
  • 【0基础3ds Max】创建标准基本体(长方体、球体、圆柱体等)理论
  • 驾驭未来:深度体验 Flet 0.7.0 的重大变革与服务化架构
  • 【Datawhale组队学习202509】AI硬件与机器人大模型 task01 具身智能基础
  • Go语言高并发编程全面解析:从基础到高级实战
  • leetcode算法刷题的第三十八天
  • RHEL 兼容发行版核心对比表
  • 如何解决 pip install 安装报错 ModuleNotFoundError: No module named ‘yaml’ 问题
  • 无刷电机有感方波闭环控制
  • 【EKL】
  • 设计模式-模板方法模式详解(2)
  • 算法(一)双指针法
  • C语言指针深度解析:从核心原理到工程实践
  • hsahmap的寻址算法和为是你扩容为2的N次方
  • ​​[硬件电路-243]:电源纹波与噪声
  • Kurt-Blender零基础教程:第1章:基础篇——第2节:认识界面
  • Kurt-Blender零基础教程:第1章:基础篇——第1节:下载与键位
  • 袋鼠参谋 - 美团推出的餐饮行业经营决策 AI 助手
  • 09-Redis 哈希类型深度解析:从命令实操到对象存储场景落地
  • 【论文阅读】MaskGIT: Masked Generative Image Transformer
  • Maya绑定基础知识总结合集:父子关系和父子约束对比
  • 从假设检验到数据驱动决策:统计推断的技术实战与方法论深度拆解