Seata AT解决脏读问题
2022-08-31 16:07:25 15 举报
Seata AT解决脏读问题
作者其他创作
大纲/内容
updateAll
注册分支事务,获取全局锁
查询前置镜像
捕获锁冲突异常后,回滚,释放本地锁,尝试重新竞争本地锁
updateB发生异常,导致全局回滚
发生脏读的情况
undolog和业务数据一起入库
class YourBussinessService { DbServiceA serviceA; DbServiceB serviceB; @GlobalTransactional public boolean updateAll(DTO dto) { serviceA.update(dto.getA()); serviceB.update(dto.getB()); } public boolean queryA(DTO dto) { serviceA.query(dto.getA()); }}
数据库提交
class YourBussinessService { DbServiceA serviceA; DbServiceB serviceB; @GlobalTransactional public boolean updateAll(DTO dto) { serviceA.update(dto.getA()); serviceB.update(dto.getB()); } @GlobalLock public boolean queryA(DTO dto) { serviceA.selectForUpdate(dto.getA()); }}class DbServiceA { @Transactional public boolean update(A a) { }}
获得本地锁
等待本地锁(读锁)
执行业务sql
业务二
解决方案:查询方法@GlobalLock+select for update
查询出业务一修改后的数据
释放本地锁
获得本地锁(读锁)
updateB()
准备undolog
可能会等待本地锁超时
业务一
queryA
查询全局锁。如果全局锁已被占用,则抛出锁冲突异常
select for update
等待本地锁
updateA
业务一调用updateAll,业务二直接调用queryA
updateA()
根据查询出来的数据进行操作,但由于业务一全局回滚了,数据库的数据重新变成了以前的数据,导致业务二读到的是脏数据
获得全局锁,查询A
查询后置镜像
全局完成,释放全局锁
0 条评论
下一页