您的位置:首页 > 数据库 > MySQL

死锁-1.0.2

2016-02-26 23:31 525 查看
If a secondary index is used in a search and index record locks to be set are exclusive(如果在查询中使用了二级索引,索引记录会被加上排他锁), InnoDB also retrieves the corresponding clustered index records and sets locks on them(InnoDB会检索符合条件的集群索引,给他们加上锁).

Gap locking is not needed for statements that lock rows using a unique index to search for a unique row(对于使用唯一索引去查找唯一记录行的语句,并不需要间隙锁). (This does not include the case that the search condition includes only some columns of a multiple-column unique index(但这并不包括查询条件中仅仅包含多列唯一索引的部分列的情况); in that case, gap locking does occur(这种情况下间隙锁还会发生).) For example, if the id column has a unique index(如果id列存在唯一索引), the following statement uses only an index-record lock for the row having id value 100 and it does not matter whether other sessions insert rows in the preceding gap(下面的记录仅仅会在id=100这行记录上设置一个索引记录锁,而不管别的会话是否在之前的间隙插入行):

SELECT * FROM child WHERE id = 100;


If id is not indexed or has a nonunique index(如果id不是索引或者没有唯一索引), the statement does lock the preceding gap(该语句就会锁住之前的间隙).

It is also worth noting here that conflicting locks can be held on a gap by different transactions. For example, transaction A can hold a shared gap lock (gap S-lock) on a gap while transaction B holds an exclusive gap lock (gap X-lock) on the same gap. The reason conflicting gap locks are allowed is that if a record is purged from an index, the gap locks held on the record by different transactions must be merged.

需要注意的是:不同的事务获取同一间隙锁会发生冲突。举个例子,在同一个间隙上,事务A获取了间隙的读锁而事务B获取了排他锁。间隙锁之所以会冲突,是因为当一条记录从索引中移除,不同的事务在这条记录上加的锁就必须合并。

Gap locks in InnoDB are “purely inhibitive”, which means they only stop other transactions from inserting to the gap. They do not prevent different transactions from taking gap locks on the same gap. Thus, a gap X-lock has the same effect as a gap S-lock.

InnoDB中的间隙锁有比较明确的抑制性,意思就是说:他们仅仅阻止别的事务插入该间隙。他们并不会阻止不同的事务在相同的间隙获取锁,因此间隙读锁和间隙写锁有相同的影响。

A type of gap lock called an insert intention gap lock is set by INSERT operations prior to row insertion. This lock signals the intent to insert in such a way that multiple transactions inserting into the same index gap need not wait for each other if they are not inserting at the same position within the gap. Suppose that there are index records with values of 4 and 7. Separate transactions that attempt to insert values of 5 and 6, respectively, each lock the gap between 4 and 7 with insert intention locks prior to obtaining the exclusive lock on the inserted row, but do not block each other because the rows are nonconflicting.

在插入记录之前首先会设置一个插入意向间隙锁,这个锁表明该事务准备去插入了。在一个相同的索引间隙,如果多个事务之间并没有在相同的位置插入数据,那么彼此之间并不会等待。假设有索引记录4和7,单个事务准备去插入5和6,每个事务都在获取排他锁之前都用意向插入间隙锁了4和7之间的间隙,但是他们并不会阻塞彼此,因为插入的行的位置是不冲突的。

The following example demonstrates a transaction taking an insert intention lock prior to obtaining an exclusive lock on the inserted record. The example involves two clients, A and B.

下面的例子展示一个事务在获取排他锁之前插入了意向锁。这个例子设计两个客户端A和B。

Client A creates a table containing two index records (90 and 102) and then starts a transaction that places an exclusive lock on index records with an ID greater than 100. The exclusive lock includes a gap lock before record 102:

客户端A创建了一个表,包含两个索引记录(90和102),然后开始一个事务,在ID大于100的记录索引上加排他锁,这个排他锁包含了102之前的间隙锁。

mysql> CREATE TABLE child (id int(11) NOT NULL, PRIMARY KEY(id)) ENGINE=InnoDB;
mysql> INSERT INTO child (id) values (90),(102);


mysql> START TRANSACTION;
mysql> SELECT * FROM child WHERE id > 100 FOR UPDATE;


Client B begins a transaction to insert a record into the gap. The transaction takes an insert intention lock while it waits to obtain an exclusive lock.

客户端B开始在该间隙插入一条记录,该事务在等待获取排他锁的同时设置了插入意向锁。等待获取插入意向锁。

mysql> START TRANSACTION;
mysql> INSERT INTO child (id) VALUES (101);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  mysql