• MySQL 中NOWAIT及SKIP LOCKED的使用示例


    本文测试数据库

    /*
     Navicat Premium Data Transfer
    
     Source Server         : 127.0.0.1
     Source Server Type    : MySQL
     Source Server Version : 80015
     Source Host           : localhost:3306
     Source Schema         : hrm_db
    
     Target Server Type    : MySQL
     Target Server Version : 80015
     File Encoding         : 65001
    
     Date: 02/08/2022 10:15:15
    */
    
    SET NAMES utf8mb4;
    SET FOREIGN_KEY_CHECKS = 0;
    
    -- ----------------------------
    -- Table structure for dept_inf
    -- ----------------------------
    DROP TABLE IF EXISTS `dept_inf`;
    CREATE TABLE `dept_inf`  (
      `ID` int(11) NOT NULL AUTO_INCREMENT,
      `NAME` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
      `REMARK` varchar(300) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      PRIMARY KEY (`ID`) USING BTREE
    ) ENGINE = InnoDB AUTO_INCREMENT = 17 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
    
    -- ----------------------------
    -- Records of dept_inf
    -- ----------------------------
    INSERT INTO `dept_inf` VALUES (1, '技术部', '技术部');
    INSERT INTO `dept_inf` VALUES (2, '运营部', '运营部');
    INSERT INTO `dept_inf` VALUES (3, '财务部', '财务部');
    INSERT INTO `dept_inf` VALUES (5, '总公办', '总公办');
    INSERT INTO `dept_inf` VALUES (6, '市场部', '市场部');
    INSERT INTO `dept_inf` VALUES (7, '教学部', '教学部');
    INSERT INTO `dept_inf` VALUES (10, '测试001', '这是测试001');
    INSERT INTO `dept_inf` VALUES (11, '测试001', '这是测试001');
    INSERT INTO `dept_inf` VALUES (12, '测试001', '这是测试001');
    INSERT INTO `dept_inf` VALUES (13, '测试3', '这是测试001');
    INSERT INTO `dept_inf` VALUES (14, '测试005', '这是测试001');
    INSERT INTO `dept_inf` VALUES (15, 'CS', 'CS');
    INSERT INTO `dept_inf` VALUES (16, '修改。。。', 'CS');
    
    -- ----------------------------
    -- Table structure for document_inf
    -- ----------------------------
    DROP TABLE IF EXISTS `document_inf`;
    CREATE TABLE `document_inf`  (
      `ID` int(11) NOT NULL AUTO_INCREMENT,
      `TITLE` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
      `filename` varchar(300) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
      `REMARK` varchar(300) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      `CREATE_DATE` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
      `USER_ID` int(11) NULL DEFAULT NULL,
      PRIMARY KEY (`ID`) USING BTREE,
      INDEX `FK_DOCUMENT_USER`(`USER_ID`) USING BTREE,
      CONSTRAINT `FK_DOCUMENT_USER` FOREIGN KEY (`USER_ID`) REFERENCES `user_inf` (`ID`) ON DELETE RESTRICT ON UPDATE RESTRICT
    ) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
    
    -- ----------------------------
    -- Table structure for employee_inf
    -- ----------------------------
    DROP TABLE IF EXISTS `employee_inf`;
    CREATE TABLE `employee_inf`  (
      `ID` int(11) NOT NULL AUTO_INCREMENT,
      `DEPT_ID` int(11) NOT NULL,
      `JOB_ID` int(11) NOT NULL,
      `NAME` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
      `CARD_ID` varchar(18) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
      `ADDRESS` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
      `POST_CODE` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      `TEL` varchar(16) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      `PHONE` varchar(11) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
      `QQ_NUM` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      `EMAIL` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
      `SEX` int(11) NOT NULL DEFAULT 1,
      `PARTY` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      `BIRTHDAY` datetime(0) NULL DEFAULT NULL,
      `RACE` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      `EDUCATION` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      `SPECIALITY` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      `HOBBY` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      `REMARK` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      `CREATE_DATE` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
      PRIMARY KEY (`ID`) USING BTREE,
      INDEX `FK_EMP_DEPT`(`DEPT_ID`) USING BTREE,
      INDEX `FK_EMP_JOB`(`JOB_ID`) USING BTREE,
      CONSTRAINT `FK_EMP_DEPT` FOREIGN KEY (`DEPT_ID`) REFERENCES `dept_inf` (`ID`) ON DELETE RESTRICT ON UPDATE RESTRICT,
      CONSTRAINT `FK_EMP_JOB` FOREIGN KEY (`JOB_ID`) REFERENCES `job_inf` (`ID`) ON DELETE RESTRICT ON UPDATE RESTRICT
    ) ENGINE = InnoDB AUTO_INCREMENT = 21 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
    
    -- ----------------------------
    -- Records of employee_inf
    -- ----------------------------
    INSERT INTO `employee_inf` VALUES (1, 1, 8, '爱丽丝', '4328011988', '广州天河', '510000', '020-77777777', '13902001111', '36750066', '251425887@qq.com', 0, '党员', '1980-01-01 00:00:00', '满', '本科', '美声', '唱歌', '四大天王', '2016-03-14 11:35:18');
    INSERT INTO `employee_inf` VALUES (2, 2, 1, '杰克', '22623', '43234', '42427424', '42242', '4247242', '42424', '251425887@qq.com', 2, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2016-03-14 11:35:18');
    INSERT INTO `employee_inf` VALUES (3, 1, 2, 'bb', '432801197711251038', '广州', '510000', '020-99999999', '13907351532', '36750064', '36750064@qq.com', 1, '党员', '1977-11-25 00:00:00', '汉', '本科', '计算机', '爬山', '无', '2016-07-14 09:54:52');
    
    -- ----------------------------
    -- Table structure for job_inf
    -- ----------------------------
    DROP TABLE IF EXISTS `job_inf`;
    CREATE TABLE `job_inf`  (
      `ID` int(11) NOT NULL AUTO_INCREMENT,
      `NAME` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
      `REMARK` varchar(300) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      PRIMARY KEY (`ID`) USING BTREE
    ) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
    
    -- ----------------------------
    -- Records of job_inf
    -- ----------------------------
    INSERT INTO `job_inf` VALUES (1, '职员', '职员');
    INSERT INTO `job_inf` VALUES (2, 'Java开发工程师', 'Java开发工程师');
    INSERT INTO `job_inf` VALUES (3, 'Java中级开发工程师', 'Java中级开发工程师');
    INSERT INTO `job_inf` VALUES (4, 'Java高级开发工程师', 'Java高级开发工程师');
    INSERT INTO `job_inf` VALUES (5, '系统管理员', '系统管理员');
    INSERT INTO `job_inf` VALUES (6, '架构师', '架构师');
    INSERT INTO `job_inf` VALUES (7, '主管', '主管');
    INSERT INTO `job_inf` VALUES (8, '经理', '经理');
    INSERT INTO `job_inf` VALUES (9, '总经理', '总经理');
    
    -- ----------------------------
    -- Table structure for notice_inf
    -- ----------------------------
    DROP TABLE IF EXISTS `notice_inf`;
    CREATE TABLE `notice_inf`  (
      `ID` int(11) NOT NULL AUTO_INCREMENT,
      `TITLE` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
      `CONTENT` text CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
      `CREATE_DATE` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
      `USER_ID` int(11) NULL DEFAULT NULL,
      PRIMARY KEY (`ID`) USING BTREE,
      INDEX `FK_NOTICE_USER`(`USER_ID`) USING BTREE,
      CONSTRAINT `FK_NOTICE_USER` FOREIGN KEY (`USER_ID`) REFERENCES `user_inf` (`ID`) ON DELETE RESTRICT ON UPDATE RESTRICT
    ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
    
    -- ----------------------------
    -- Table structure for user_inf
    -- ----------------------------
    DROP TABLE IF EXISTS `user_inf`;
    CREATE TABLE `user_inf`  (
      `ID` int(11) NOT NULL AUTO_INCREMENT,
      `loginname` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
      `PASSWORD` varchar(16) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
      `USERSTATUS` int(11) NOT NULL DEFAULT 1,
      `createdate` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
      `username` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      PRIMARY KEY (`ID`) USING BTREE
    ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
    
    -- ----------------------------
    -- Records of user_inf
    -- ----------------------------
    INSERT INTO `user_inf` VALUES (1, 'admin', '123456', 2, '2016-03-12 09:34:28', '超级管理员');
    
    -- ----------------------------
    -- Procedure structure for SAD_LOCK_TEST
    -- ----------------------------
    DROP PROCEDURE IF EXISTS `SAD_LOCK_TEST`;
    delimiter ;;
    CREATE PROCEDURE `SAD_LOCK_TEST`()
    BEGIN
    SET @sum:=0;
    SET @sum:=0;
    START TRANSACTION;
    SELECT * FROM dept_inf WHERE ID =16 FOR UPDATE;
    WHILE @sum < 1000000 DO
    SET @sum = @sum +1;
    END WHILE;
    SELECT @sum;
    COMMIT;
    END
    ;;
    delimiter ;
    
    SET FOREIGN_KEY_CHECKS = 1;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182

    准备一个事务,用于加锁

    CREATE DEFINER=`root`@`%` PROCEDURE `SAD_LOCK_TEST`()
    BEGIN
    SET @sum:=0;
    SET @sum:=0;
    START TRANSACTION;
    SELECT * FROM dept_inf WHERE ID =16 FOR UPDATE;
    WHILE @sum < 1000000 DO
    SET @sum = @sum +1;
    END WHILE;
    SELECT @sum;
    COMMIT;
    END
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    其中,给表 dept_inf的ID=16该行加上了锁。即是,其他的语句要修改、删除该行或者查询获取该行的锁,则需要等锁释放之后才能执行。注意,插入给表一行没有影响,因为该锁只是针对ID=16这一行,而插入一行是表的行为(除非是其他事务给表加了锁),或者对其他行(ID != 16的行)的操作均没有影响。

    例子
    在这里插入图片描述

    • 原文
    InnoDB supports NOWAIT and SKIP LOCKED options with SELECT ... FOR SHARE and SELECT ... FOR UPDATE locking read statements. NOWAIT causes the statement to return immediately if a requested row is locked by another transaction. SKIP LOCKED removes locked rows from the result set. See Locking Read Concurrency with NOWAIT and SKIP LOCKED.
    
    • 1
    • 翻译
    InnoDB 支持在读锁语句SELECT ... FOR SHARE 和 SELECT ... FOR UPDATE 中使用NOWAIT和SKIP LOCKED选项。如果请求的行被另外一个事务锁住了,那么NOWAIT就会是语句立即返回。SKIP LOCKED会从结果集中移除被锁住的行。见文档“ Locking Read Concurrency with NOWAIT and SKIP LOCKED”
    
    • 1
    • 例子

    直接运行
    在这里插入图片描述
    先运行左边带锁的事务,再运行右边的查询语句
    在这里插入图片描述
    使用NOWAIT 选项,直接返回,不等其他事务释放锁
    在这里插入图片描述
    参考:MySQL的UPDATE及SELECT…FOR UPDATE语句关于锁的一些简单验证

  • 相关阅读:
    Redis系列:RDB内存快照提供持久化能力
    闭包(C#)
    [Leetcode] 0058. 最后一个单词的长度
    Cy3.5-PEG-NHS ester,Cy3.5-聚乙二醇-琥珀酰亚胺酯,Cy3.5-PEG-SC/SE
    形态的分类稳定性
    Rasa-笔记
    transformer一统天下?depth-wise conv有话要说
    2023年11月25日(星期六)骑行三家村
    计算机毕业设计选题推荐-教师薪酬管理系统-Java项目实战
    Tomcat多实例及nginx反向代理tomcat
  • 原文地址:https://blog.csdn.net/qq_29025955/article/details/126116545