MySQL 锁机制和事务

行级锁是施加在索引行数据上的锁,比如SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE语句是在t.c1=10的索引行上增加锁 ,来阻止其他事务对对应索引行的insert/update/delete操作。 

当一个InnoDB表没有任何索引时, 则行级锁会施加在隐含创建的聚簇索引上,所以说当一条sql没有走任何索引时,那么将会在每一条聚集索引后面加X(排它)锁,这个类似于表锁,但原理上和表锁应该是完全不同的

1

2

 

mysql> create table temp(id int,name varchar(10));

mysql> insert into temp values(1,'a'),(2,'b'),(3,'c');

 

开启两个会话链接,链接同一个数据库,模拟排他锁

+ View Code?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

 

session1:

 

##update加排他锁

mysql> set autocommit=0;  #模拟开启一个事务会话

Query OK, 0 rows affected (0.00 sec)

mysql> update temp set name='aa' where >

Query OK, 1 row affected (0.00 sec)

Rows matched: 1 Changed: 1 Warnings: 0

 

session2:

##update等待第一个锁释放 

mysql> update temp set name='bb'where >

 

session1

##commit释放锁

mysql> commit;

Query OK, 0 rows affected (0.00 sec)

 

session2

等待结束释放锁

update操作才会成功

Query OK, 1 row affected (5.81 sec)

Rows matched: 1  Changed: 1  Warnings: 0

 

看看事务的详细信息:

+ View Code?

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

 

session1:

set autocommit=0;

update temp set name='a' where >

 

session2:

select trx_id,trx_state,trx_started,trx_tables_locked,trx_rows_locked from

information_schema.innodb_trx\G;

*************************** 1. row ***************************

          trx_id: 35455759  #事务id

        trx_state: RUNNING  #事务状态

      trx_started: 2018-10-08 18:15:26  #事务开启时间

trx_tables_locked: 1

  trx_rows_locked: 4

1 row in set (0.00 sec)

 

update temp set name='b' where >

 

 

session3:

#查看锁等待

select * from information_schema.innodb_lock_waits;

#查看锁状态

select trx_id,trx_state,trx_started,trx_tables_locked,trx_rows_locked from information_schema.innodb_trx;

#查看锁的信息

select lock_id,lock_trx_id,lock_mode,lock_type,lock_index,lock_rec,lock_data from information_schema.innodb_locks;

 

看看该事务的锁信息

MySQL 锁机制和事务

MySQL 锁机制和事务

MySQL 锁机制和事务

lock_type : RECORD 行级锁 
lock_index:GEN_CLUSE_INDEX 聚集索引

给temp表加一个主键索引在看看

alter table temp add primary key(id); ##增加索引之后,记得把前面事务提交

MySQL 锁机制和事务

1

2

3

4

5

6

7

8

9

10

11

12

 

session1:

update加排它锁

 

set autocommit=0;

update temp set name='a' where >

 

session2:

update temp set name='b' where >

update不需要等待第一个锁释放,直接执行成功

 

session1: 进行提交事务

commit;

 

  

MySQL 锁机制和事务

间隔锁

当 我们用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件 的已有数据记录的索引项加锁;对于键值在条件范围内但并不存在的记录,叫做“间隙(GAP)”, InnoDB也会对这个“间隙”加锁 

间隔锁是施加在索引记录之间的间隔上的锁, 锁定一个范围的记录、但不包括记录本身,比如SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE语句,尽管有可能对c1字段来说当前表里没有=15 的值,但还是会阻止=15的数据的插入操作,是因为间隔锁已经把索引查询范围内的间隔数据也都锁住了

间隔锁的使用只在部分事务隔离级别才是生效的 

间隔锁只会阻止其他事务的插入操作

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/6c657295ebb4837b7471e8c9aab82ec3.html