supremum pseudo-record鎖影響

G8bao7發表於2014-01-14
在開發中,經常會做這類的判斷:根據主鍵值查詢,如果不存在,則插入;否則更新。
例如
表結構

點選(此處)摺疊或開啟

  1. CREATE TABLE `t` (
  2.   `id` INT(11) NOT NULL AUTO_INCREMENT,
  3.   `val` BIGINT(20) NOT NULL,
  4.   PRIMARY KEY (`id`)
  5. ) ENGINE=INNODB DEFAULT CHARSET=utf8;

使用方式

點選(此處)摺疊或開啟

  1. START TRANSACTION;

  2. -- 方式一
  3. SELECT id FROM `t` WHERE `id` ='N' LOCK IN SHARE MODE;
  4. IF (FOUND_ROWS() <= 0) THEN
  5.     -- do insert
  6. end if;

  7. -- 方式二
  8. UPDATE `t` SET `val` = 'XX' WHERE `id` ='N';
  9. IF (ROW_COUNT() <= 0) THEN
  10.     -- do insert
  11. end if;

  12. commit;

當N超過表裡的最大值時,兩種方式都會對primary索引的 supremum pseudo-record加一個X鎖,導致其他的insert會被阻塞
supremum pseudo-record :相當於比索引中所有值都大,但卻不存在索引中,相當於最後一行之後的間隙鎖
For the last interval, the next-key lock locks the gap above the largest value in the index and the supremumpseudo-record having a value higher than any value actually in the index. The supremum is not a real index record, so, in effect, this next-key lock locks only the gap following the largest index value.

建議改成原子操作, 不會阻塞其他insert

點選(此處)摺疊或開啟

  1. START TRANSACTION;
  2. insert into ... on duplicate key update `val`='XX';

  3. commit;

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26250550/viewspace-1070422/,如需轉載,請註明出處,否則將追究法律責任。

相關文章