MySQL中的 ”SELECT FOR UPDATE“ 一次实践

最近工作中遇到一个问题,两个不同的线程会对数据库里的一条数据做修改,如果不加锁的话,会得到错误的结果。 就用了MySQL中for update 这种方式来实现 本文主要测试主键、唯一索引和普通索引使用for update 会锁哪些数据 使用两个console来模拟两个事务运行的情况

背景

最近工作中遇到一个问题,两个不同的线程会对数据库里的一条数据做修改,如果不加锁的话,会得到错误的结果。

就用了MySQL中for update 这种方式来实现

本文主要测试主键、唯一索引和普通索引使用for update 会锁哪些数据

使用两个console来模拟两个事务运行的情况

表结构

/*
 Navicat Premium Data Transfer

 Source Server         : localhost
 Source Server Type    : MySQL
 Source Server Version : 50730
 Source Host           : localhost:3306
 Source Schema         : test

 Target Server Type    : MySQL
 Target Server Version : 50730
 File Encoding         : 65001

 Date: 18/12/2020 20:28:58
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for select_for_update_test
-- ----------------------------
DROP TABLE IF EXISTS select_for_update_test;
CREATE TABLE select_for_update_test (
  id int(11) NOT NULL AUTO_INCREMENT,
  name varchar(20) NOT NULL,
  age int(11) NOT NULL,
  PRIMARY KEY (id),
  UNIQUE KEY name (name),
  KEY age (age)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of select_for_update_test
-- ----------------------------
BEGIN;
INSERT INTO select_for_update_test VALUES (1, 'a', 1);
INSERT INTO select_for_update_test VALUES (2, 'b', 2);
INSERT INTO select_for_update_test VALUES (3, 'c', 3);
INSERT INTO select_for_update_test VALUES (4, 'd', 4);
INSERT INTO select_for_update_test VALUES (5, 'e', 5);
INSERT INTO select_for_update_test VALUES (6, 'f', 6);
INSERT INTO select_for_update_test VALUES (7, 'g', 7);
INSERT INTO select_for_update_test VALUES (8, 'h', 8);
COMMIT;

SET FOREIGN_KEY_CHECKS = 1;

主键的影响

  • 选一行数据
console1

START TRANSACTION;
SELECT * FROM select_for_update_test WHERE id = 1 FOR UPDATE;
console2
SELECT * FROM select_for_update_test WHERE id = 1 FOR UPDATE; 会锁

SELECT * FROM select_for_update_test WHERE id = 2 FOR UPDATE; 不会锁
  • 选取多行记录
console1

START TRANSACTION;
SELECT * FROM select_for_update_test WHERE id >= 2 AND id
console2

SELECT * FROM select_for_update_test WHERE id = 1 FOR UPDATE; 不会锁

SELECT * FROM select_for_update_test WHERE id = 3 FOR UPDATE; 会锁

SELECT * FROM select_for_update_test WHERE id = 6 FOR UPDATE; 会锁

唯一索引的影响

  • 选一行数据
console1

START TRANSACTION;
SELECT * FROM select_for_update_test WHERE name = 'a' FOR UPDATE;
console2

SELECT * FROM select_for_update_test WHERE name = 'a' FOR UPDATE; 会锁

SELECT * FROM select_for_update_test WHERE name = 'b' FOR UPDATE; 不会锁
  • 选取多行记录1
console1

START TRANSACTION;
SELECT * FROM select_for_update_test WHERE name >= 'b' AND name
console2

SELECT * FROM select_for_update_test WHERE name = 'a' FOR UPDATE; 会锁

SELECT * FROM select_for_update_test WHERE name = 'c' FOR UPDATE; 会锁

SELECT * FROM select_for_update_test WHERE name = 'f' FOR UPDATE; 会锁
  • 选取多行记录2
console1

START TRANSACTION;
SELECT * FROM select_for_update_test WHERE name >= 'c' AND name
console2

SELECT * FROM select_for_update_test WHERE name = 'b' FOR UPDATE; 不会锁

SELECT * FROM select_for_update_test WHERE name = 'c' FOR UPDATE; 会锁

SELECT * FROM select_for_update_test WHERE name = 'f' FOR UPDATE; 会锁

普通索引的影响

  • 选一行数据
console1

START TRANSACTION;
SELECT * FROM select_for_update_test WHERE age = 1 FOR UPDATE;
console2

SELECT * FROM select_for_update_test WHERE age = 1 FOR UPDATE; 会锁

SELECT * FROM select_for_update_test WHERE age = 2 FOR UPDATE; 不会锁
  • 选取多行记录1
console1

START TRANSACTION;
SELECT * FROM select_for_update_test WHERE age >= 2 AND age
console2

SELECT * FROM select_for_update_test WHERE age = 1 FOR UPDATE; 会锁

SELECT * FROM select_for_update_test WHERE age = 3 FOR UPDATE; 会锁

SELECT * FROM select_for_update_test WHERE age = 6 FOR UPDATE; 会锁

SELECT * FROM select_for_update_test WHERE age = 8 FOR UPDATE; 不会锁
  • 选取多行记录2
console1

START TRANSACTION;
SELECT * FROM select_for_update_test WHERE age >= 3 AND age
console2

SELECT * FROM select_for_update_test WHERE age = 2 FOR UPDATE; 不会锁

SELECT * FROM select_for_update_test WHERE age = 3 FOR UPDATE; 会锁

SELECT * FROM select_for_update_test WHERE age = 6 FOR UPDATE; 会锁

SELECT * FROM select_for_update_test WHERE age = 8 FOR UPDATE; 不会锁

Original: https://www.cnblogs.com/eaglelihh/p/14156817.html
Author: eaglelihh
Title: MySQL中的 ”SELECT FOR UPDATE“ 一次实践

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/587228/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 如何有效地开发 Jmix 扩展组件

    扩展组件的概念在使用 Jmix 框架开发中扮演着非常重要的角色。我们将在本文探索什么是扩展组件以及 Jmix Studio 在扩展组件开发和应用程序模块化方面能给开发者带来什么帮助…

    Java 2023年6月15日
    079
  • Spring Ioc容器xml配置

    Spring Ioc容器xml配置基本结构: <?xml version="1.0" encoding="UTF-8"?> &l…

    Java 2023年6月15日
    065
  • spring Aop实现防止重复提交

    1.先定义一个注解 2.实现一个aop import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.Stri…

    Java 2023年5月30日
    070
  • 2021 CCPC女生赛

    newbie,A了五题铜牌收工比赛时和队友悠哉游哉做题,想着干饭,最后幸好没滚出铜尾。贴一下比赛过的代码 队友A的,判断正反方向序列是否符合要求 /*** * @Author: _…

    Java 2023年6月5日
    087
  • SpringMVC使用指南

    SpringMVC使用指南 一、SpringMVC的工作原理 1.1 SpringMVC的原理流程 图片地址:22. Web MVC framework 用户发起请求,请求被拦截到…

    Java 2023年6月6日
    089
  • SpringBoot为什么是默认单例的:

    SpringBoot为什么是默认单例的: 好处:1)提升性能,减少了新生成实例的消耗新生成实例消耗包括两方面,第一,spring会通过反射或者cglib来生成bean实例,其次,给…

    Java 2023年6月6日
    090
  • ArrayList 和 LinkedList 的区别是什么?

    说一下 ArrayList 的优缺点 ArrayList的优点如下:ArrayList 底层以数组实现,是一种随机访问模式。ArrayList 实现了RandomAccess 接口…

    Java 2023年6月13日
    075
  • 甲骨文严查Java授权,换openJDK要避坑

    背景 外媒The Register报道,甲骨文稽查企业用户,近期开始将把过去看管较松散的Java授权加入。 甲骨文针对标准版Java(Java SE)有2种商业授权。2019年4月…

    Java 2023年5月29日
    068
  • 朱晔和你聊Spring系列S1E11:小测Spring Cloud Kubernetes @ 阿里云K8S

    朱晔和你聊Spring系列S1E11:小测Spring Cloud Kubernetes @ 阿里云K8S 有关Spring Cloud Kubernates(以下简称SCK)详见…

    Java 2023年5月30日
    071
  • 抵达一颗安静的心

    素心免忧虑,心内止如水。俯仰观天地,信步采撷美。 ……其实啊,我只是像平常人一样,在工作和生活中探索和修行而已。 我喜欢漫步在宁静的自然中。花木草叶,鸟鸣溪…

    Java 2023年6月9日
    086
  • SMBMS(超市订单管理系统)项目从零开始搭建

    如果需要完整的系统可以加我qq:1842329236 一、搭建一个maven web项目 新建一个maven,并且使用模板 maven的详细创建,及配置请看这篇文章https://…

    Java 2023年6月14日
    096
  • 部署相关

    部署相关 C1.jar包启动 &#x95EE;&#x9898;&#x73B0;&#x8C61;&#xFF1A; nacos注释使用中文,通过…

    Java 2023年6月16日
    072
  • JPA 入门实战(1)–简介

    JPA(Java Persistence API) 是 SUN 公司推出的一套 ORM 规范,充当 Java 对象和关系数据库系统之间的桥梁;本文主要介绍其基本概念。 1、JPA …

    Java 2023年6月16日
    079
  • 手把手教你如何高效落地多项目管理 | 一看既会

    如何高效落地多项目管理,云效Projex 是新一代企业级研发协作平台,集成了敏捷研发项目管理的最佳实践,提供了针对项目、迭代、需求、缺陷等多个维度的协同管理以及相关的统计报告,让研…

    Java 2023年6月8日
    097
  • linux下一条指令安装服务器图像化界面:宝塔

    yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6….

    Java 2023年6月14日
    0109
  • Java广度优先爬虫示例(抓取复旦新闻信息)

    以下内容仅供学习交流使用,请勿做他用,否则后果自负。 一.使用的技术 这个爬虫是近半个月前学习爬虫技术的一个小例子,比较简单,怕时间久了会忘,这里简单总结一下.主要用到的外部Jar…

    Java 2023年5月29日
    075
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球