MySQL: lock

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:
Insert image description here
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.

Guess you like

Origin blog.csdn.net/amadeus_liu2/article/details/133036000