The locks are normally next-key locks that also block inserts into the “gap” immediately before the record. mysql> select @@tx_isolation; +-----------------+ | @@tx_isolation | +-----------------+ | REPEATABLE-READ | +-----------------+ 1 row in set (0.00 sec) 第一种情况 更新列没有索引: CREATE TABLE `SmsTest` ( `sn` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增编号', `phoneNo` int(16) NOT NULL, `channelType` int(11) DEFAULT NULL COMMENT '通道识别', `status` tinyint(4) NOT NULL COMMENT '短信转态,1.发送成功,2.发送失败,3.发送异常', PRIMARY KEY (`sn`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='短信发送成功记录表'; mysql> show create table SmsTest\G; *************************** 1. row *************************** Table: SmsTest Create Table: CREATE TABLE `SmsTest` ( `sn` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增编号', `phoneNo` int(16) NOT NULL, `channelType` int(11) DEFAULT NULL COMMENT '通道识别', `status` tinyint(4) NOT NULL COMMENT '短信转态,1.发送成功,2.发送失败,3.发送异常', PRIMARY KEY (`sn`) ) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=utf8 COMMENT='短信发送成功记录表' 1 row in set (0.00 sec) ERROR: No query specified mysql> show index from SmsTest; +---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | +---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | SmsTest | 0 | PRIMARY | 1 | sn | A | 16 | NULL | NULL | | BTREE | | | +---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 1 row in set (0.00 sec) mysql> select * from SmsTest; +----+---------+-------------+--------+ | sn | phoneNo | channelType | status | +----+---------+-------------+--------+ | 1 | 1 | 2 | 1 | | 2 | 2 | 2 | 1 | | 3 | 3 | 2 | 1 | | 4 | 4 | 2 | 1 | | 5 | 5 | 2 | 1 | | 6 | 6 | 2 | 1 | | 7 | 7 | 2 | 1 | | 8 | 8 | 2 | 1 | | 9 | 9 | 2 | 1 | | 10 | 10 | 1 | 1 | | 16 | 16 | 45 | 56 | | 17 | 17 | 2 | 1 | | 18 | 18 | 1 | 1 | | 19 | 19 | 1 | 1 | | 20 | 20 | 2 | 1 | | 21 | 10 | 1 | 1 | +----+---------+-------------+--------+ 16 rows in set (0.00 sec) /*********第一种情况 更新列没有索引: Session 1: mysql> start transaction; Query OK, 0 rows affected (0.00 sec) mysql> select * from SmsTest where phoneNo=16 for update; +----+---------+-------------+--------+ | sn | phoneNo | channelType | status | +----+---------+-------------+--------+ | 16 | 16 | 45 | 56 | +----+---------+-------------+--------+ 1 row in set (0.00 sec) mysql[192.168.11.187] processid[3] root@localhost in db[zjzc] hold transaction time 55 You have new mail in /var/spool/mail/root 进程ID为3 Session 2: mysql> start transaction; Query OK, 0 rows affected (0.00 sec) mysql> insert into SmsTest values(11,11,1,1); ##堵塞 2016-11-25 10:03:19,152,3,root,localhost,zjzc mysql[192.168.11.187] processid[3] root@localhost in db[zjzc] hold transaction time 152 112072530,26,insert into SmsTest values(11,11,1,1),112072529,3, mysql[192.168.11.187] blocking_thread[3] blocking_query[] blocking waiting_thread[26]'s insert into SmsTest values(11,11,1,1) You have new mail in /var/spool/mail/root mysql> insert into zjzc.SmsTest values(11,1,1,1); mysql> insert into zjzc.SmsTest values(110,110,1,1); ###堵塞 mysql[192.168.11.187] blocking_thread[3] blocking_query[] blocking waiting_thread[34]'s insert into zjzc.SmsTest values(110,110,1,1) mysql> insert into zjzc.SmsTest values(200,110,1,1); 112072532,34,insert into zjzc.SmsTest values(220,220,1,1),112072529,3, mysql[192.168.11.187] blocking_thread[3] blocking_query[] blocking waiting_thread[34]'s insert into zjzc.SmsTest values(220,220,1,1) Vsftp:/root# mysql -uroot -p1234567 -e"show processlist" Warning: Using a password on the command line interface can be insecure. +----+------+-----------+------+---------+------+--------+----------------------------------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+------+-----------+------+---------+------+--------+----------------------------------------------+ | 3 | root | localhost | zjzc | Sleep | 469 | | NULL | | 34 | root | localhost | zjzc | Query | 7 | update | insert into zjzc.SmsTest values(220,220,1,1) | | 41 | root | localhost | NULL | Query | 0 | init | show processlist | +----+------+-----------+------+---------+------+--------+----------------------------------------------+ 更新列没有索引,此时锁全表 /*********第一种情况 更新列有索引,但是非唯一索引 mysql> show create table zjzc.SmsTest\G; *************************** 1. row *************************** Table: SmsTest Create Table: CREATE TABLE `SmsTest` ( `sn` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增编号', `phoneNo` int(16) NOT NULL, `channelType` int(11) DEFAULT NULL COMMENT '通道识别', `status` tinyint(4) NOT NULL COMMENT '短信转态,1.发送成功,2.发送失败,3.发送异常', PRIMARY KEY (`sn`) ) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=utf8 COMMENT='短信发送成功记录表' 1 row in set (0.00 sec) ERROR: No query specified mysql> show index from SmsTest; +---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | +---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | SmsTest | 0 | PRIMARY | 1 | sn | A | 15 | NULL | NULL | | BTREE | | | +---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 1 row in set (0.00 sec) 创建索引,在phoneNo 列上 mysql> start transaction; Query OK, 0 rows affected (0.00 sec) mysql> select * from SmsTest where phoneNo=16 for update; +----+---------+-------------+--------+ | sn | phoneNo | channelType | status | +----+---------+-------------+--------+ | 16 | 16 | 45 | 56 | +----+---------+-------------+--------+ 1 row in set (0.00 sec) Session 2: mysql> insert into SmsTest values(99,9,1,1); Query OK, 1 row affected (0.00 sec) mysql> insert into SmsTest values(99,10,1,1); ##堵塞 mysql> insert into SmsTest values(11,11,1,1); ##堵塞 ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction mysql> mysql[192.168.11.187] processid[1] root@localhost in db[zjzc] hold transaction time 40 112074074,25,insert into SmsTest values(11,11,1,1),112074073,1, mysql[192.168.11.187] blocking_thread[1] blocking_query[] blocking waiting_thread[25]'s insert into SmsTest values(11,11,1,1) mysql> insert into SmsTest values(12,12,1,1); ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction mysql> insert into SmsTest values(13,13,1,1); ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction mysql> insert into SmsTest values(14,14,1,1); ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction mysql> insert into SmsTest values(14,14,1,1); ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction mysql> insert into SmsTest values(15,15,1,1); ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction mysql> insert into SmsTest values(16,16,1,1); ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction mysql> insert into SmsTest values(17,17,1,1); ERROR 1062 (23000): Duplicate entry '17' for key 'PRIMARY' mysql> insert into SmsTest values(99,17,1,1); ERROR 1062 (23000): Duplicate entry '99' for key 'PRIMARY' mysql> insert into SmsTest values(999,17,1,1); Query OK, 1 row affected (0.00 sec) 更新列上有唯一索引 ,锁住的区间为【10,16】 /*********第一种情况 更新列有索引,且是唯一索引 mysql> create unique index SmsTest_idx1 on SmsTest(phoneNo); Query OK, 0 rows affected (0.02 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> show create table SmsTest\G; *************************** 1. row *************************** Table: SmsTest Create Table: CREATE TABLE `SmsTest` ( `sn` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增编号', `phoneNo` int(16) NOT NULL, `channelType` int(11) DEFAULT NULL COMMENT '通道识别', `status` tinyint(4) NOT NULL COMMENT '短信转态,1.发送成功,2.发送失败,3.发送异常', PRIMARY KEY (`sn`), UNIQUE KEY `SmsTest_idx1` (`phoneNo`) ) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8 COMMENT='短信发送成功记录表' 1 row in set (0.00 sec) ERROR: No query specified Session 1: mysql> start transaction; Query OK, 0 rows affected (0.00 sec) mysql> select * from SmsTest where phoneNo=16 for update; +----+---------+-------------+--------+ | sn | phoneNo | channelType | status | +----+---------+-------------+--------+ | 16 | 16 | 45 | 56 | +----+---------+-------------+--------+ 1 row in set (0.00 sec) Session 2: mysql> use zjzc; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> insert into SmsTest values(11,11,1,1); Query OK, 1 row affected (0.00 sec) mysql> rollback; Query OK, 0 rows affected (0.00 sec) mysql> insert into SmsTest values(12,12,1,1); Query OK, 1 row affected (0.00 sec) mysql> rollback; Query OK, 0 rows affected (0.00 sec) mysql> insert into SmsTest values(13,13,1,1); Query OK, 1 row affected (0.00 sec) mysql> rollback; Query OK, 0 rows affected (0.00 sec) mysql> insert into SmsTest values(14,14,1,1); Query OK, 1 row affected (0.00 sec) mysql> rollback; Query OK, 0 rows affected (0.00 sec) mysql> insert into SmsTest values(15,15,1,1); Query OK, 1 row affected (0.00 sec) mysql> rollback; Query OK, 0 rows affected (0.00 sec) mysql> insert into SmsTest values(16,16,1,1); ##堵塞 ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql 区间锁 对于没有索引 非唯一索引 唯一索引 各种情况
转载本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
Java如何设计一个全局唯一订单号
Java如何设计一个全局唯一订单号
自增 数据中心 数据库 唯一订单号