1. table
CREATE TABLE `dog` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`age` int(11) DEFAULT NULL,
`weight` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_age` (`age`)
) ENGINE=InnoDB AUTO_INCREMENT=51 DEFAULT CHARSET=utf8
2. Insert data:
3. Test of primary key locking (the unique index and primary key conditions are exactly the same)
Open two navicat windows and execute set autocommit=0 respectively to turn off automatic submission.
1. Execute in two windows respectively:
select * from dog where id=35 lock in share mode;
None will block.
2. One window execution:
select * from dog where id=35 lock in share mode;
Another window executes:
select * from dog where id=35 for update;
Then the second window reports: Lock wait timeout exceeded; try restarting transaction
3. One window executes:
select * from dog where id=35 lock in share mode;
Another window executes:
update dog set weight=1111 where id=35;
Then the second window reports: Lock wait timeout exceeded; try restarting transaction
Conclusion: When performing an equivalent query on the primary key, if the record exists, a record lock will only be added to the record.
4. One window execution:
select * from dog where id=38 lock in share mode;
The record with id 38 does not exist.
Execute in another window:
update dog set weight=1111 where id=40;
The update can be successful, but if:
insert into dog(id,age,weight) values(37,8,32);
insert into dog(id,age,weight) values(39,8,32);
Conclusion
: When performing an equivalent query on the primary key, if the record does not exist, only the interval where the record is located will be removed, that is, a gap lock will be added. For example, in this example, the temporary key lock is (35,40] , then what is actually added is the gap lock (35,40)
5. One window execution:
select * from dog where id>34 and id<40 lock in share mode;
Another window executes:
insert into dog(id,age,weight) values(32,8,32);
execution succeed.
If another window executes:
insert into dog(id,age,weight) values(38,8,32);
Blocking
conclusion: The first query above will initially experience two gap locks (30,35], (35,40]. Because the condition id>34 hits the record id=35, the first gap lock is degraded For the record lock, only the record with id=35 is locked. Because the condition of id<40 does not hit the record of (35, 40], the temporary key lock, so the temporary key lock degenerates into the gap lock (35, 40), so in the end The locked interval is [35,40), so the data with id 32 can be inserted, but the record with id 38 cannot be inserted.
4. Test of ordinary index locking:
1. One window execution:
select * from dog where age=20 for update;
Another window executes:
insert into dog(id,age,weight) values(84,17,32);
insert into dog(id,age,weight) values(85,23,32);
All blocked.
Conclusion: For ordinary indexes, when equal value query and records exist, a temporary key lock will be added to the interval where the record is located, and a gap lock will be added to the next temporary key lock interval. The first query above will first add a temporary key lock to the interval (10, 20), and then add a gap lock to the interval (20, 30). Therefore, the locked interval is (10, 30), and the following statement will Does not block:
update dog set weight=3 where id=10;
update dog set weight=3 where id=30;
insert into dog(id,age,weight) values(85,7,32);
2. One window execution:
select * from dog where age=43 for update;
The record with age 43 does not exist.
The open interval locked is (40, 50).
Another window executes:
update dog set weight=3 where id=40;
update dog set weight=3 where id=50;
All executed successfully. If the following statement is executed, it will block
insert into dog(id,age,weight) values(86,42,32);
insert into dog(id,age,weight) values(86,45,32);
Conclusion: Ordinary index, equivalent query, when the record does not exist, lock the open interval where the record is located
3. One window execution:
select * from dog where age>44 and age< 48 for update;
Another window executes:
insert into dog(id,age,weight) values(86,42,32);
insert into dog(id,age,weight) values(86,49,32);
will block. Execute the following statement:
update dog set weight=6 where id=50;
success.
Analysis: The first statement above locks the open interval (40, 50), that is, a gap lock is added.
If you change the first statement to:
select * from dog where age>23 and age<= 30 for update;
Another window executes:
insert into dog(id,age,weight) values(86,22,32);
insert into dog(id,age,weight) values(86,33,32);
will block
the execution of the following statements:
update dog set weight=35 where id=35;
will execute successfully.
Analysis: The first statement above locks the interval (20, 30) and the interval (30, 35), that is, the interval (20, 35) is locked.
5. Test of locking columns without index:
1. One window execution:
select * from dog where weight=3 for update;
Another window executes:
insert into dog(id,age,weight) values(99,99,99);
Then the second window reports: Lock wait timeout exceeded; try restarting transaction
2. One window executes:
select * from dog where weight=34 for update;
Another window executes:
insert into dog(id,age,weight) values(99,99,99);
Then the second window reports: Lock wait timeout exceeded; try restarting transaction
3. One window execution:
select * from dog where weight>5 for update;
Another window executes:
insert into dog(id,age,weight) values(1,1,1);
Then the second window reports: Lock wait timeout exceeded; try restarting transaction
Conclusion: When locking a column without an index, whether the data is found by the equal query, the data is not found by the equal query, or the range query, a table lock is added to the entire table, and other transactions cannot perform any operations on the table. Insert or update operation.