Innodb 锁

来源:互联网 发布:mysql order by 原理 编辑:程序博客网 时间:2024/05/01 00:39

Innodb实现了标准的行级锁,以下列举了事务隔离级别设置为重复读时应用设计应该注意的地方。

SELECT ... FROM is a consistent read, reading a snapshot of the database and setting no locks unless the transaction isolation level is set to SERIALIZABLE.

1.当 Query 无法利用索引的时候, Innodb 会放弃使用行级别锁定而改用表级别的锁定,随后的dml(insert , update, delete)都会等待,造成并发性能的降低;

--t表a列没有索引的情况下,由于升级到了表级锁,session B处于等待 ,直到session A提交或回滚之后,session B才能继续执行。--session Amysql> start transaction;Query OK, 0 rows affected (0.00 sec)mysql> update t set b=2 where a=2;Query OK, 1 row affected (0.00 sec)Rows matched: 1  Changed: 1  Warnings: 0--session Bmysql> start transaction;Query OK, 0 rows affected (0.00 sec)mysql> update t set b=1 where a=1;ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
2.当 Query 使用的索引并不包含所有过滤条件的时候,数据检索使用到的索引键所涉及的数据可能有部分并不属于该 Query 的结果集的行列,但是也会被锁定,因为间隙锁锁定的是一个范围,而不是具体的索引键;

--session B处于等待 ,直到session A提交或回滚之后,session B才能继续执行。--session Amysql> select * from t;+------+------+| a    | b    |+------+------+|    2 |    2 ||    3 |    3 ||    4 |    4 ||    5 |    5 ||    1 | 1000 ||    6 |    6 ||    7 |    7 ||    8 |    8 |+------+------+8 rows in set (0.00 sec)mysql> create index ind_t_a on t(a);Query OK, 0 rows affected (0.20 sec)Records: 0  Duplicates: 0  Warnings: 0mysql> start transaction;Query OK, 0 rows affected (0.00 sec)mysql> update t set b=0 where a >6 and a < 10; --包含a=9,所以session B会等待Query OK, 2 rows affected (0.00 sec)Rows matched: 2  Changed: 2  Warnings: 0--session Bmysql> start transaction;Query OK, 0 rows affected (0.00 sec)mysql> insert into t values(9,9);ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
3.当 Query 在使用索引定位数据的时候,如果使用的索引键一样但访问的数据行不同的时候(索引只是过滤条件的一部分),一样会被锁定

--session B处于等待 ,直到session A提交或回滚之后,session B才能继续执行。--session Amysql> select * from t;+------+------+| a    | b    |+------+------+|    2 |    2 ||    2 |    3 ||    4 |    4 ||    5 |    5 ||    1 | 1000 ||    6 |    6 ||    7 |    0 ||    8 |    0 |+------+------+8 rows in set (0.00 sec)mysql> start transaction;Query OK, 0 rows affected (0.00 sec)mysql> update t b=888 where a=2 and b=2;ERROR 1064 (42000): You have an error in your SQL smysql> update t set b=888 where a=2 and b=2;Query OK, 1 row affected (0.00 sec)Rows matched: 1  Changed: 1  Warnings: 0--session Bmysql> start transaction;Query OK, 0 rows affected (0.00 sec)mysql> update t set b=999 where a=2 and b=3;ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

原创粉丝点击