MySQL 锁机制和事务(2)

gap lock的前置条件: 
1 事务隔离级别为REPEATABLE-READ, innodb_locks_unsafe_for_binlog参数为0,且sql走的索引为非唯一索引(无论是等值检索还是范围检索)

2 事务隔离级别为REPEATABLE-READ, innodb_locks_unsafe_for_binlog参数为0,且sql是一个范围的当前读操作,这时即使不是非唯一索引也会加gap lock

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

 

update加排他锁和间隔锁

set autocommit=0;

mysql> update temp2 set name='abc' where id between 4 and 6;

Query OK, 0 rows affected (0.01 sec)

Rows matched: 0  Changed: 0  Warnings: 0

 

session2:

insert into temp2 values(4,'d');

会等待第一个锁释放

 

session1:

释放锁

commit;

 

session2:

Query OK, 1 row affected (7.65 sec)

等待结束释放锁 插入数据成功

 

例子如果链接1的update语句是update temp set name=‘abc’ where id >4; 而链接2的 
插入数据的>

Next-key锁

在默认情况下, mysql的事务隔离级别是可重复读,并且innodb_locks_unsafe_for_binlog 
参数为0,这时默认采用next-key locks。所谓Next-Key Locks, 就是记录锁和间隔锁的结合,即除了锁住记录本身,还要再锁住索引之间的间隙。

插入意图锁

插入意图锁是在插入数据时首先获得的一种间隔锁, 对这种间隔锁只要不同的事务插 入的数据位置是不一样的,虽然都是同一个间隔,也不会产生互斥关系

比如有一个索引有4和7两个值,如果两个事务分别插入5和6两个值时,虽然两个事务 
都会在索引4和7之间施加间隔锁,但由于后续插入的数值不一样,所以两者不会互斥

比如下例中事务A对索引>100的值施加了排他间隔锁,而事务B在插入数据之前就试 

图先施加插入意图锁而必须等待

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

 

CREATE TABLE child (id int(11) NOT NULL, PRIMARY KEY(id)) ENGINE=InnoDB;

INSERT INTO child (id) values (90),(102);

#开启事务A

START TRANSACTION;

#增加排它间隔锁

SELECT * FROM child WHERE id > 100 FOR UPDATE;

+-----+

| id  |

+-----+

| 102 |

+-----+

1 row in set (0.00 sec)

 

 

另一个session窗口,开启事务B:

START TRANSACTION;

INSERT INTO child (id) VALUES (101);

这时候会有锁等待

 

可以通过show engine innodb status命令查看插入意向锁被阻止

MySQL 锁机制和事务

自增锁

自增锁是针对事务插入表中自增列时施加的一种特殊的表级锁,即 
当一个事务在插入自增数据时,另一个事务必须等待前一个事务完 
成插入,以便获得顺序的自增值

参数innodb_autoinc_lock_mode可以控制自增锁的使用方法

InnoDB锁相关系统变量

查看当前系统隔离级别

1

2

3

4

5

6

 

show variables like 'tx_isolation';

 +---------------+-----------------+

| Variable_name | Value          |

+---------------+-----------------+

| tx_isolation  | REPEATABLE-READ |

+---------------+-----------------+

 

查看是否开启自动提交

1

2

 

show variables like 'autocommit';

show variables like 'innodb_table_locks';

 

查看innodb事务等待事务的超时时间(秒)

1

2

3

4

5

6

 

mysql> show variables like 'innodb_lock_wait_timeout';

+--------------------------+-------+

| Variable_name            | Value |

+--------------------------+-------+

| innodb_lock_wait_timeout | 50    |

+--------------------------+-------+

 

innodb_locks_unsafe_for_binlog参数用来控制innodb中是否允许间隔锁,默认是OFF代表允许间隔锁,设置成ON则代表不使用间隔锁,只是使用行级锁

+ View Code?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

 

• mysql> show variables like 'innodb_locks_unsafe_for_binlog';

• +--------------------------------+-------+

• | Variable_name | Value |

• +--------------------------------+-------+

• | innodb_locks_unsafe_for_binlog | OFF |

• +--------------------------------+-------+

• 在my.cnf中配置innodb_locks_unsafe_for_binlog=on选项

• 链接1:

• mysql> set autocommit=0;

• mysql> update temp set name='abc' where id>=4;

• 链接2:

• mysql> set autocommit=0;

• Query OK, 0 rows affected (0.00 sec)

• mysql> insert into temp values(4,‘abc’); ##未出现等待的情况

• Query OK, 1 row affected (0.00 sec)

 

InnoDB事务隔离级别

InnoDB存储引擎提供了四种事务隔离级别,分别是:

READ UNCOMMITTED:读取未提交内容

READ COMMITTED:读取提交内容

REPEATABLE READ:可重复读,默认值。

SERIALIZABLE:串行化

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

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