MySQL中的 ”SELECT FOR UPDATE“ 一次实践
背景
最近工作中遇到一个问题,两个不同的线程会对数据库里的一条数据做修改,如果不加锁的话,会得到错误的结果。
就用了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 <= 5 FOR UPDATE;
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; 不会锁
- 选取多行记录
console1
START TRANSACTION;
SELECT * FROM select_for_update_test WHERE `name` >= 'b' AND `name` <= 'e' FOR UPDATE;
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; 会锁
- 选取多行记录
console1
START TRANSACTION;
SELECT * FROM select_for_update_test WHERE `name` >= 'c' AND `name` <= 'e' FOR UPDATE;
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; 不会锁
- 选取多行记录
console1
START TRANSACTION;
SELECT * FROM select_for_update_test WHERE age >= 2 AND age <= 5 FOR UPDATE;
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; 不会锁
- 选取多行记录
console1
START TRANSACTION;
SELECT * FROM select_for_update_test WHERE age >= 3 AND age <= 5 FOR UPDATE;
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; 不会锁
MySQL中的 ”SELECT FOR UPDATE“ 一次实践的更多相关文章
- MySQL中ON DUPLICATE KEY UPDATE使用
今天做推断插入用到了MySQL中ON DUPLICATE KEY UPDATE,如今Mark下面! 假设你想做到数据库中没有数据的话插入数据.有数据的话更新数据,那么你能够选择ON DUPLICATE ...
- sql判断以逗号分隔的字符串中是否包含某个字符串--------MYSQL中利用select查询某字段中包含以逗号分隔的字符串的记录方法
sql判断以逗号分隔的字符串中是否包含某个字符串---------------https://blog.csdn.net/wttykj/article/details/78520933 MYSQL中利 ...
- 【转载】MySQL事务以及SELECT ... FOR UPDATE的使用
MySQL中的事务,默认是自动提交的,即autocommit = 1: 但是这样的话,在某些情形中就会出现问题:比如: 如果你想一次性插入了1000条数据,mysql会commit1000次的, 如果 ...
- mysql事务,select for update,及数据的一致性处理
在MySQL的InnoDB中,预设的Tansaction isolation level 为REPEATABLE READ(可重读) 在SELECT 的读取锁定主要分为两种方式: SELECT ... ...
- 一个MySQL中两表联合update的例子(并带有group by分组)
内容简介 本文主要展示了在MySQL中,使用两表联合的方式来更新其中一个表字段值的SQL语句. 也就是update table1 join table2 on table1.col_name1=tab ...
- MYSQL中的SELECT查询时进行运算
SELECT在mysql中是查询表中的数据的作用,但也可以在查询的时候直接进行运算,然后返回查询后的结果 比如 )) FROM username2 其中的IFNULL函数是对adven数据进行判断,若 ...
- MYSQL中利用select查询某字段中包含以逗号分隔的字符串的记录方法
首先我们建立一张带有逗号分隔的字符串. CREATE TABLE test(id int(6) NOT NULL AUTO_INCREMENT,PRIMARY KEY (id),pname VARCH ...
- 【数据库系列】MySql中的select的锁表范围
由于InnoDB预设的是Row-Level Lock,只有明确指定主键的时候MySql才会执行Row lock,否则MySql将会执行Table Lock. 1.明确指定主键则是行锁 2.明确指定主键 ...
- mysql中的select语句where条件group by ,having , order by,limit的顺序及用法
-- 语法: SELECT select_list FROM table_name [ WHERE search_condition ] [ GROUP BY group_by_expression ...
随机推荐
- 面试半年!三面阿里,四面蚂蚁金服,居然倒在了一个Java集合之Map上?
Map接口 Map与Collection并列存在.用于保存具有映射关系的数据:key-valueMap中的key和value都可以是任何引用类型的数据Map中的key用set来存放,不允许重复,即同一 ...
- dsu on tree (树上启发式合并) 详解
一直都没出过算法详解,昨天心血来潮想写一篇,于是 dsu on tree 它来了 1.前置技能 1.链式前向星(vector 建图) 2.dfs 建树 3.剖分轻重链,轻重儿子 重儿子 一个结点的所有 ...
- JDBC【1】-- 入门之增删改查
目录 1.jdbc是什么 2.使用IDEA开发 2.1 创建数据库,数据表 2.2 使用IDEA创建项目 1.jdbc是什么 JDBC(Java DataBase Connectivity,java数 ...
- jvm参数与生产配置
堆内存分配:JVM初始分配的内存由-Xms指定,默认是物理内存的1/64JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制:空 ...
- FDR校正
一.假设检验 假设检验的基本思路是: 设立零假设(null hypothesis)H0,以及与零假设H0相对应的非零假设(alternative hypothesis)H1,在假设H0成立的前提下,计 ...
- FPGA 串口
VerilogHDL那些事儿_建模篇(黑金FPGA开发板配套教程) 作者:akuei2 说明:参照该书将部分程序验证学习一遍 学习时间:2014年5月3号 主要收获: 1. 对串口有初步了解: 2. ...
- Alpha冲刺-第三次冲刺笔记
Alpha冲刺-冲刺笔记 这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzzcxy/2018SE2 这个作业要求在哪里 https://edu.cnblogs. ...
- rest-framework 分页器
一 简单分页(查看第n页,每页显示n条) from rest_framework.pagination import PageNumberPagination # 一 基本使用:url=url=htt ...
- MVTMVC 区别
1,MVC的意思是 M:model V:views C:controller model是 主要是封装对数据库层的访问,对数据库中的数据进行增删改查操作 views 是 用于封装结果, 生程页面展示 ...
- 老猿学5G专栏文章目录
☞ ░ 前往老猿Python博文目录 ░ 一.3GPP规范文档及其他推荐阅读博文 老猿学5G扫盲贴:3GPP规范文档命名规则及同系列文档阅读指南 老猿学5G扫盲贴:3GPP规范中部分与计费相关的规范序 ...