日常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. js es6 介绍set,WeakSet

    前言 介绍一下es6 的set 和 weakset 正文 set ES6 提供了新的数据结构 Set.它类似于数组,但是成员的值都是唯一的,没有重复的值. Set 本身是一个构造函数,用来生成 Set ...

  2. tensorflow安装-【老鱼学tensorflow2】

    tensorflow版本已经升级到了2.x,其在易用性上大大增强,主要是由于API采用了keras的方式,大大简化了开发工作. 安装 pip3 install tensorflow 验证 输入如下代码 ...

  3. NodeJS安装cnpm

    介绍: NPM(Node Package Manager):Node的包管理器. CNPM(Chinese CPM):中国的NPM(国内使用,网速较快). 配置步骤 用npm安装cnpm npm in ...

  4. Causal Inference理论学习篇-Tree Based-Causal Forest

    广义随机森林 了解causal forest之前,需要先了解其forest实现的载体:GENERALIZED RANDOM FORESTS[6](GRF) 其是随机森林的一种推广, 经典的随机森林只能 ...

  5. 力扣387(java)-字符串中的第一个唯一字符(简单)

    题目: 给定一个字符串 s ,找到 它的第一个不重复的字符,并返回它的索引 .如果不存在,则返回 -1 . 示例 1: 输入: s = "leetcode"输出: 0示例 2: 输 ...

  6. PolarDB开源未来将有哪些新动向?阿里云数据库开源负责人来解答

    简介: 在10月25日由阿里云开发者社区.PolarDB开源社区.infoQ联合举办的「开源人说」第三期--<数据库PolarDB专场>沙龙上,阿里云数据库开源负责人.数据库资深技术专家王 ...

  7. Dubbo Mesh:从服务框架到统一服务控制平台

    简介: Apache Dubbo 是一款 RPC 服务开发框架,用于解决微服务架构下的服务治理与通信问题,官方提供了 Java.Golang 等多语言 SDK 实现. 作者:Dubbo 社区   Ap ...

  8. 基于MaxCompute+开放搜索的电商、零售行业搜索开发实践

    ​简介: 搜索一直是电商行业流量来源的核心入口之一,如何搭建电商行业搜索并提升搜索效果,一直是电商行业开发者努力攻克的难题.基于传统数据库或开源引擎虽然能够搭建基础搜索服务,但随着商品数据的增多和业务 ...

  9. dotnet 6 通过 DOTNET_ROOT 让调起的应用的进程拿到共享的运行时文件夹

    我的应用是独立发布的,在用户的设备上不需要额外去安装 .NET 运行时.但是我的应用有一个需求是下载另一个应用作为插件,由本应用调起插件进程.本文告诉大家如何解决调用插件的进程时,赋值给插件进程运行时 ...

  10. 原生js写悬浮广告效果

    网上抄的,改成vue写法失败,下一篇是自己写的vue版本的 <html> <head> <meta http-equiv="Content-Type" ...