日常Bug排查-MVCC和for update混用导致读数据不一致

前言

日常Bug排查系列都是一些简单Bug的排查。笔者将在这里介绍一些排查Bug的简单技巧,同时顺便积累素材。

Bug现场

又是喜闻乐见的读数据不一致的问题。这次的问题是这样,业务在一个事务中更新A和B两个表的两个数据。但是在另一个事务中只看到了A的更新,而B依旧是更新之前的值。说好的原子性感觉又被打破了。如下图所示:

思路

在将这两个请求的SQL按照时序画出来的时候,笔者立马就明白了相关问题所在。核心就在于数据库是RR隔离级别的,同时业务在查询A的时候使用的是Select for update,在查询B的时候使用的是普通的Select。这么使用的原因可能是觉得所有的查询都需要先查A再查B,那么只需要对A加锁就行,减少了数据库锁的数量。

但是,这里是有一个问题的,就是对B表的查询用的是普通的Select,也就是使用了MySQL的MVCC机制。而MySQL MVCC的默认创建时刻就是事务的第一个不带for update的普通Select(具体原理见笔者的博客https://my.oschina.net/alchemystar/blog/1927425)。那么我们就可以从上面的SQL顺序可以看到,在事务1开始之前就已经创建了视图,此时的视图是A1和B1。那么由于RR,查询B表的普通Select看到的自然是B1,而select for update不走MVCC,于是看到的是A2。如下图所示:

解决方案

让业务对B表的查询也用Select for update即可,相比于不一致增加的一点非热点行锁的性能可以忽略不计。

总结

MVCC和数据库锁两者采用了不同的机制,如果不清楚其中的原理可能会导致不一致的现象出现。同时,在这次的问题中业务对于B表不用锁这样的优化实际上是一个负优化。这再次提醒我们,不要过早优化!

日常Bug排查-MVCC和for update混用导致读数据不一致的更多相关文章

  1. 日常Bug排查-抛异常不回滚

    日常Bug排查-抛异常不回滚 前言 日常Bug排查系列都是一些简单Bug排查,笔者将在这里介绍一些排查Bug的简单技巧,同时顺便积累素材_. Bug现场 最近有人反映java应用操作数据库的时候,抛异 ...

  2. 日常Bug排查-系统失去响应-Redis使用不当

    日常Bug排查-系统失去响应-Redis使用不当 前言 日常Bug排查系列都是一些简单Bug排查,笔者将在这里介绍一些排查Bug的简单技巧,同时顺便积累素材_. Bug现场 开发反应线上系统出现失去响 ...

  3. 日常Bug排查-消息不消费

    日常Bug排查-消息不消费 前言 日常Bug排查系列都是一些简单Bug排查,笔者将在这里介绍一些排查Bug的简单技巧,同时顺便积累素材_. Bug现场 某天下午,在笔者研究某个问题正high的时候.开 ...

  4. 日常Bug排查-Nginx重复请求?

    日常Bug排查-Nginx重复请求? 前言 日常Bug排查系列都是一些简单Bug排查,笔者将在这里介绍一些排查Bug的简单技巧,其中不乏一些看起来很低级但很容易犯的问题. 问题现场 有一天运维突然找到 ...

  5. 记一次线上bug排查-quartz线程调度相关

    记一次线上bug排查,与各位共同探讨. 概述:使用quartz做的定时任务,正式生产环境有个任务延迟了1小时之久才触发.在这一小时里各种排查找不出问题,直到延迟时间结束了,该任务才珊珊触发.原因主要就 ...

  6. 解Bug之路-记一次中间件导致的慢SQL排查过程

    解Bug之路-记一次中间件导致的慢SQL排查过程 前言 最近发现线上出现一个奇葩的问题,这问题让笔者定位了好长时间,期间排查问题的过程还是挺有意思的,正好博客也好久不更新了,就以此为素材写出了本篇文章 ...

  7. 记一次偶发的bug排查——redis-py-cluster库的bug

     排查流水账: 通过平台监控,发现很多偶发的查看推荐列表的接口时延大于0.5s 写单元测试,不能重现.在测试环境不能重现.只有在正式环境可以偶发重现. 通过日志埋点,等待重现 不断地加日志埋点后发现耗 ...

  8. wordpress插件bug排查后记(记一次由于开启memecached引起的插件bug)

    这篇文章是写给自己的. 周三的时候我在维护公司的一个wordpress项目页面时发现了一个非常奇怪的情况:当我尝试更新网站上的一个页面后,在wordpress后台的编辑器中发现其内容并没有按我预期的将 ...

  9. 团队项目-BUG排查-ADT工程 To Android Studio 一整天的排查日记

    4-22 10:44至4-23 0:45 ①打开Eclipse从Github上Clone MathsApp到本机,报错'Unable to resolve target'android-19' ②尝试 ...

  10. 一次压力测试Bug排查-epoll使用避坑指南

    Bug复现 使用Webbench对服务器进行压力测试,创建1000个客户端,并发访问服务器10s,正常情况下有接近8万个HTTP请求访问服务器. 结果显示仅有7个请求被成功处理,0个请求处理失败,服务 ...

随机推荐

  1. gitlib配置

    第1步:下载Java并安装Java.一般来说下载jdk对应的版本就行. 第2步:配置Java环境变量,具体如下: 1. 新建:变量名:JAVA_HOME:变量值:C:\Program Files\Ja ...

  2. spring cloud 学习笔记 基础工程的构建(一)

    前言 学习一下spring cloud,只是过一遍微服务的一些现代化工具,微服务其实一直都存在,去公司的时候发现一个问题,即使有些项目没有用到现代这些什么docker.k8s,其实也是微服务,微服务一 ...

  3. MySQL组合索引

    MySQL组引合索优化SQL 我的场景 200w左右的数据,后面会更多 使用定时任务爬取数据插入到自己的数据库.要保证数据的唯一性,所以我用了组合唯一索引. 表结构 最初的组合索引 SQL执行和exp ...

  4. 精通中间件测试:Asp.Net Core实战指南,提升应用稳定性和可靠性

    引言 在上一章节我们实战了在Asp.Net Core中的项目实战,这一章节讲解一下如何测试Asp.Net Core的中间件. TestServer 还记得我们在集成测试中提供的TestServer吗? ...

  5. 力扣613(MySQL)-直线上的最近距离(简单)

    题目: 表 point 保存了一些点在 x 轴上的坐标,这些坐标都是整数. 写一个查询语句,找到这些点中最近两个点之间的距离. 最近距离显然是 '1' ,是点 '-1' 和 '0' 之间的距离.所以输 ...

  6. 力扣7(java)-整数反转(中等)

    题目: 给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果. 如果反转后整数超过 32 位的有符号整数的范围 [−231,  231 − 1] ,就返回 0. 假设环境不允许存 ...

  7. Apache RocketMQ 的 Service Mesh 开源之旅

    作者 | 凌楚   阿里巴巴开发工程师 导读:自 19 年底开始,支持 Apache RocketMQ 的 Network Filter 历时 4 个月的 Code Review(Pull Reque ...

  8. EventBridge 与 FC 一站式深度集成解析

    ​简介:本篇文章通过对 EventBridge 与 FC 一站式深度集成解析和集成场景的介绍,旨在帮助大家更好的了解面对丰富的事件时,如何使用 EventBridge 与 FC 的一站式集成方案,快速 ...

  9. 从 RxJS 到 Flink:如何处理数据流?

    简介: 前端开发的本质是什么?响应式编程相对于 MVVM 或者 Redux 有什么优点?响应式编程的思想是否可以应用到后端开发中?本文以一个新闻网站为例,阐述在前端开发中如何使用响应式编程思想:再以计 ...

  10. 阿里云 EDAS 3.0 助力唱鸭提升微服务幸福感

    简介: EDAS 3.0 提供的微服务治理,很好的支持了唱鸭 APP 实现微服务应用的发布.监控.管理等日常业务场景.作为运维侧的重要平台和开框架的提供者,EDAS 3.0 帮助用户可以更专注业务.微 ...