Seata---AT模式会不会出现脏读

一句话回答:会出现一种脏读情况,只不过和传统脏读不一样

一句话回答:会出现一种脏读情况,只不过和传统脏读不一样,传统的脏读指的是读取到其他(MySQL本地事务)事务未提交的数据。而Seata会出现,读取到其他(分支事务)(本地事务)事务已提交但可能被全局回滚的数据。

(听上去有点绕?你看完下面的介绍在回过头来看,就能明白了。。。)

想要回答好这个问题,需要先了解一下Seata的AT模式的工作原理。

AT模式的核心机制是两阶段提交:

●第一阶段:本地事务立即提交,释放本地锁,数据对其他事务可见。 ●第二阶段:全局事务根据协调结果决定提交或回滚(通过undo log补偿)。

那么,大家仔细想一下这个场景,其实会出现一种情况,那就是如果全局事务最终回滚,其他事务可能在P第一阶段结束后、第二阶段回滚前读取到已提交但即将被撤销的数据,导致逻辑上的脏读。

案例

现在有三个模块,交易模块、订单模块和库存模块。在一次下单过程中,为了保证一致性,代码可能如下:

java 复制代码
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;

@Service
public class TradeService {
    @Autowired
    private InventoryService inventoryService;
    @Autowired
    private OrderService orderService;

    @GlobalTransactional
    public boolean buy() {
        //库存扣减   
        inventoryService.decreaseInvenroty();       
        //创建订单   
        orderService.createOrder();  }  
    }

在这个分布式事务中(@GlobalTransactional开启的分布式事务),先调库存服务进行库存扣减,然后再调用订单服务进行订单创建。那么整个(大致)流程就是这样的:

这里需要注意的是,在第二步调库存模块之后,库存模块的在数据库上的操作,都是基于数据库的本地事务的,他需要通过数据库的本地事务来保障undolog(Seata用到的的undolog,和MySQL中MVCC的那个undolog不是一个)和库存扣减的原子性,并且这一步执行完之后,数据库的本地事务是要做提交的!

这很关键,数据库的本地事务做了提交,事务提交了,也就意味着,不管在什么样的事务隔离级别下,其他的事务都能查到提交后的新值了。

那么试想一下,如果在第二步执行成功之后,库存已经完成了扣减,但是第三步执行订单创建执行失败了,这时候整个分布式事务是要回滚的,那么就会基于库存库中的undolog做回滚。那么,在提交后,回滚前,如果有其他的事务来查询库存数据,是不是就读到了一个本该回滚的值?

这是不是也是一种脏读,只不过这个脏读并不是MySQL的本地事务中的脏读,而是Seata全局事务中的脏读。即在全局事务过程中,别的事务可能会读到全局事务尚未提交(后面可能会回滚)的数据。

AT如何避免脏读

AT模式的脏读是他的实现机制导致的,因为他的第一阶段是借助分支事务实现的,利用分支事务的ACID保证业务操作和undolog的写入的原子性。但是第一阶段执行完,整个全局事务并没有确定要不要提交,还是有可能会回滚的。一旦发生回滚,那么在回滚前,就会能读到脏数据了。

那么这个问题如何避免呢?

也有一个办法解决 就是在查询的时候加上 @GlobalTransactional + select * ... for update 但是这个比较笨拙 但是确实可以解决这个棘手的问题

在就没啥好办法,因为事务已经提交了,没办法避免其他事务的读取,就算能实现,也会大大降低可用性。所以如果不能接受脏读,那么不要使用AT模式,可以选择其他的事务方案,比如TCC。

相关推荐
蝎子莱莱爱打怪3 分钟前
那不是我的黑历史,那是我的来时路啊!😭😭
后端·程序员
用户298698530144 分钟前
Java 实现 Word 文档文本与图片提取的方法
java·后端
蝎子莱莱爱打怪11 分钟前
XZLL-IM干货系列 04|Netty 长连接实战:Pipeline 怎么排、心跳怎么跳、连接怎么管
后端·微服务·面试
Csvn17 分钟前
Rsync 文件同步与增量备份 — 运维的数据守门员
后端
苏三说技术19 分钟前
推荐一个牛逼的智能代码审查系统
后端
倾颜27 分钟前
从 GitHub Actions 到本地兜底发布:AI Mind 容器化上线的一次真实收口
后端
像我这样帅的人丶你还34 分钟前
Java 后端详解(二):注解、参数绑定、评论与用户认证
后端
用户7623524259135 分钟前
深入理解AQS之独占锁ReentrantLock
后端
用户7623524259141 分钟前
理解 CAS & Atomic 原子操作类
后端
SimonKing1 小时前
铁子,IntelliJ IDEA 2026.1.3来了,升不升?
java·后端·程序员