回顾事务的特性

本文深入探讨了事务的四大特性:原子性、一致性、隔离性和持久性,以及它们在数据库管理系统中的作用。同时,文章详细阐述了三类数据读问题(脏读、不可重复读、幻读)和两类数据更新问题,分析了不同问题的成因和解决策略。针对MySQL和Oracle数据库,介绍了事务的隔离级别设置和查看方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.事务的四大特性

原子性:事务必须是一个不可分割的整体,要么做完,要么不做。

一致性:事务执行前和执行后来源和去向保持平衡,数据不会被破坏。

隔离性:并发时每个事务是隔离的,相互不影响。

持久性:事务一旦成功提交,就会永久保存到数据库中。

 

原子性是基础,隔离性是手段,持久性是目的,真正的老大就是一致性。

2.三类数据读问题

2-1Dirty Read(脏读)

事务 A 读取了事务 B 未提交的数据,并在这个基础上又做了其他操作。

回顾事务的特性220.png

2-2Unrepeatable Read(不可重复读)

事务 A 读取了事务 已提交的更改数据。

回顾事务的特性273.png

2-3Phantom Read(幻读)

事务 A 读取了事务 B 已提交的新增数据。

回顾事务的特性318.png

2-4不可重复读和幻读的区别


1不可重复读的重点是修改避免不可重复度需要锁行

2幻读的重点在于新增或者删除避免幻读需要锁表

3.两类数据更新问题

3-1第一类丢失更新(撤销覆盖)

A事务撤销时,把已经提交的B事务的更新数据覆盖了。

回顾事务的特性443.png

3-2第二类丢失更新(提交覆盖)

B事务覆盖A事务已经提交的数据,造成A事务所做操作丢失

回顾事务的特性491.png

4.隔离的级别

回顾事务的特性501.png

4-1 MySQL

mysql默认的事务处理级别是'REPEATABLE-READ',也就是可重复读

4-1-1.查看当前会话隔离级别

select @@tx_isolation;

4-1-2.查看系统当前隔离级别

select @@global.tx_isolation;

4-1-3.设置当前会话隔离级别

set session transaction isolatin level repeatable read;

4-1-4.设置系统当前隔离级别

set global transaction isolation level repeatable read;

4-2 Oracle

oracle数据库支持READ COMMITTED 和 SERIALIZABLE这两种事务隔离级别。

 

默认系统事务隔离级别是READ COMMITTED,也就是读已提交

4-2-1.查看系统默认事务隔离级别,也是当前会话隔离级别

--首先创建一个事务

declare

     trans_id Varchar2(100);

  begin

     trans_id := dbms_transaction.local_transaction_id( TRUE );

  end; 

--查看事务隔离级别

 

SELECT s.sid, s.serial#,

 

  CASE BITAND(t.flag, POWER(2, 28))

    WHEN 0 THEN 'READ COMMITTED'

    ELSE 'SERIALIZABLE'

  END AS isolation_level

FROM v$transaction t

JOIN v$session s ON t.addr = s.taddr AND s.sid = sys_context('USERENV', 'SID');

<think>好的,用户现在想了解Spring事务的传播特性。我需要根据之前提供的引用内容来详细解答这个问题。首先,我应该回顾用户提供的引用材料,确保信息的准确性。用户提供的引用[1]、[2]、[3]、[4]、[5]都涉及到Spring事务的不同方面,特别是传播特性和配置方法。 首先,我需要明确Spring事务传播特性的定义和作用。根据引用[2],事务的传播特性通过@Transactional注解的propagation属性设置,而Propagation枚举类对应不同的传播行为。用户可能需要知道每个传播行为的具体含义和使用场景。 接下来,我需要列举并详细解释每个传播特性。例如,PROPAGATION_REQUIRED是默认的,如果当前没有事务,就新建一个,如果有则加入。这适用于大多数情况。而PROPAGATION_REQUIRES_NEW则是无论当前是否存在事务,都新建一个,这在需要独立事务时使用,比如日志记录。 同时,用户可能关心这些传播特性如何在实际代码中应用。例如,引用[2]提到使用@Transactional注解来设置,而引用[4]展示了如何通过配置类来管理事务,比如DataSourceTransactionManager。此外,引用[3]提到了JpaTransactionManager的配置,说明不同的持久化框架可能需要不同的事务管理器。 另外,用户可能对事务的回滚机制感兴趣。引用[5]详细描述了异常时的回滚过程,提到在completeTransactionAfterThrowing方法中处理回滚,这可能涉及到检查异常类型,默认情况下Spring只对RuntimeException和Error回滚,用户可能需要配置rollbackFor属性来覆盖其他异常。 还需要注意,用户之前的问题是关于SpringBoot的优缺点,现在转向事务传播特性,可能需要稍微调整回答的侧重点,但保持技术深度。需要确保回答结构清晰,分点解释,并给出代码示例或配置示例,帮助用户理解。 最后,生成相关问题时要覆盖用户可能进一步询问的方向,比如如何选择传播特性、不同场景的应用、配置方法以及异常处理等。确保引用正确的来源,比如在解释传播特性时引用[2]和[4],在配置事务管理器时引用[3]和[4],在回滚机制时引用[5]。 总结下来,回答需要包括传播特性的定义、七种传播行为的详细解释、配置方式(注解和XML)、以及实际应用中的注意事项,如异常回滚和事务管理器选择。同时,使用代码示例和配置片段来增强说明,确保用户能够结合实际代码理解概念。</think>#### Spring事务传播特性详解 Spring事务传播特性定义了**多个事务方法相互调用时,事务如何传播**的逻辑规则,是保证数据一致性的核心机制[^2][^4]。以下详解7种传播行为及其应用场景: --- ### 一、传播特性定义与配置 1. **核心枚举类**:通过`Propagation`枚举定义7种传播行为,对应`TransactionDefinition`接口常量。 2. **配置方式**: - **注解配置**:在方法上使用`@Transactional(propagation = Propagation.REQUIRED)`[^2]。 - **XML配置**:通过`<tx:method>`标签指定传播行为[^3]。 --- ### 二、7种传播行为解析 | **传播行为** | **触发条件** | **典型场景** | |---------------------------|-----------------------------------------------------------------------------|---------------------------------------| | **REQUIRED**(默认) | 当前无事务→新建事务;当前有事务→加入该事务 | 通用型业务方法(如订单支付)[^2][^4] | | **SUPPORTS** | 当前无事务→非事务执行;当前有事务→加入该事务 | 查询方法(可适应事务或非事务环境) | | **MANDATORY** | 当前无事务→抛出异常;当前有事务→加入该事务 | 强制要求调用方必须开启事务的方法 | | **REQUIRES_NEW** | 无论当前是否有事务→始终新建独立事务,暂停原事务(若存在) | 日志记录、审计等独立操作[^2] | | **NOT_SUPPORTED** | 当前无事务→非事务执行;当前有事务→挂起原事务,非事务执行 | 需要绕过事务的方法(如调用外部API) | | **NEVER** | 当前无事务→非事务执行;当前有事务→抛出异常 | 禁止在事务中调用的方法(如数据校验) | | **NESTED** | 当前无事务→新建事务;当前有事务→创建嵌套事务(可部分回滚) | 复杂业务分层(如主流程与子流程) | --- ### 三、关键机制与源码分析 1. **事务嵌套与保存点** - **NESTED传播**依赖数据库的保存点(Savepoint)机制,允许子事务回滚不影响外层事务[^4]。 - 示例:主事务提交订单,嵌套事务扣减库存。若库存不足,仅回滚嵌套事务,不影响订单提交[^4]。 2. **事务挂起与恢复** - **REQUIRES_NEW**传播时,Spring通过`TransactionSynchronizationManager`挂起当前事务,创建新事务[^2]。 ```java // 伪代码示例:挂起当前事务 SuspendedResourcesHolder suspendedResources = suspend(existingTransaction); try { // 创建新事务 DefaultTransactionStatus newStatus = startTransaction(definition, transaction, debugEnabled, suspendedResources); // 执行业务逻辑 return invokeWithinTransaction(...); } finally { // 恢复原事务 resume(suspendedResources, existingTransaction); } ``` 3. **异常回滚规则** - 默认仅对`RuntimeException`和`Error`回滚,需通过`@Transactional(rollbackFor = Exception.class)`扩展[^5]。 - 回滚逻辑:调用链`TransactionAspectSupport.completeTransactionAfterThrowing()`→`AbstractPlatformTransactionManager.rollback()`→底层JDBC `Connection.rollback()`[^5]。 --- ### 四、配置与实战示例 1. **注解配置案例** ```java @Service public class OrderService { @Autowired private InventoryService inventoryService; @Transactional(propagation = Propagation.REQUIRED) public void createOrder(Order order) { // 主事务:保存订单 orderRepository.save(order); // 嵌套事务:扣减库存(独立回滚) inventoryService.deductStock(order.getProductId(), Propagation.NESTED); } } ``` 2. **XML配置案例** ```xml <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="create*" propagation="REQUIRED" /> <tx:method name="get*" propagation="SUPPORTS" read-only="true" /> </tx:attributes> </tx:advice> ``` --- ### 五、常见问题与解决方案 1. **事务不生效** - 原因:未启用事务管理(需添加`@EnableTransactionManagement`)、方法非public、同类内方法调用(绕过代理)[^3]。 - 解决:使用AspectJ模式或通过代理对象调用方法。 2. **嵌套事务回滚范围** - **NESTED传播**仅回滚嵌套事务内的操作,而**REQUIRES_NEW**完全独立(外层事务回滚不影响内层)[^4]。 --- ### 六、总结 - **选择依据**:根据业务逻辑的隔离性需求、数据一致性级别、性能要求综合判断。 - **最佳实践**:优先使用默认`REQUIRED`,需要强隔离时用`REQUIRES_NEW`,分层业务用`NESTED`[^4]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值