Ну тут ещё и вариант с INSERT / SELECT появился. Хотя если не работает с SELECT FOR UPDATE, то 90%, что и здесь те же яйцы в профиль.Автор оригинала: Sherman
Вроде whirlwind ответил(про gap lock) выше?
...на самом деле тут ещё обсуждается одна из немногих ценных идей MySQL (вернее, не MySQL, а InnoDB), это вот этот самый gap locking. Который идёт чуть дальше, чем требует стандарт.Автор оригинала: Sherman
Эта тема является не просто источником нескончаемого получения лулзов, но отлично показывает, что "знание" mysql - это на самом деле, знание всяческих мелких хаков, фишичек и прочих затычек, которыми программисты mysql пытаются затыкать баги в своей СУБД, вместо того, чтобы, не изобретая велосипед, просто реализовывать стандарт.
Да, пожалуй что такое и в Postgres'е работать будет через Advisory locks.Автор оригинала: MiksIr
Вариант, который fisher первый озвучил - именованные локи с именем как функция от параметров - наиболее универсальный и гибкий вариант.
Так, что insert .. (select), как я и говорил, работает точно так же, как и select for update - в том смысле, что ставит те же самые блокировки.Как это проинтерпретировать, даже и не знаю
аналогичноАвтор оригинала: Найч
не воспроизводится
mysql> CREATE TABLE `a` (
-> `x` text,
-> `s` int(11) default NULL
-> ) ENGINE=InnoDB;
Query OK, 0 rows affected (0.15 sec)
mysql> insert into a (x, s) select 'y', sleep(10)
from dual where not exists(select x from a where x='y');
ERROR 1213 (40001): Deadlock found when trying to get lock;
try restarting transaction
mysql> select version();
+--------------------+
| version() |
+--------------------+
| 5.0.75-0ubuntu10.2 |
+--------------------+
1 row in set (0.00 sec)
mysql>
Автор оригинала: crocodile2u
Провел интересный, по-моему, эксперимент с insert ... select:
КОНСОЛЬ 1:
--
mysql> CREATE TABLE `a` (
`x` text,
`s` int(11) default NULL
) ENGINE=InnoDB;
mysql> insert into a (x, s) select 'y', sleep(10) from dual where not exists(select x from a where x='y');
--
КОНСОЛЬ 2:
mysql> insert into a (x) select 'y' from dual where not exists(select x from a where x='y');
--
Спустя какое-то время (очевидно, 10 секунд - время, нужное для переключения между консолями), в первой консоли:
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
... а во второй:
Query OK, 1 row affected (7.35 sec)
Records: 1 Duplicates: 0 Warnings: 0
Как это проинтерпретировать, даже и не знаю
mysql> show engine innodb status;
LATEST DETECTED DEADLOCK
------------------------
091003 18:05:04
*** (1) TRANSACTION:
TRANSACTION 0 2310, ACTIVE 3 sec, process no 2712, OS thread id 2734521232 inserting
mysql tables in use 2, locked 2
LOCK WAIT 4 lock struct(s), heap size 320, 2 row lock(s)
MySQL thread id 1, query id 27 localhost root executing
insert into a (x) select 'y' from dual where not exists(select x from a where x='y')
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 60 n bits 72 [b]index `GEN_CLUST_INDEX` of table `test`.`a`[/b] trx id 0 2310 [b]lock_mode X[/b] insert intention waiting
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
0: len 8; hex 73757072656d756d; asc supremum;;
*** (2) TRANSACTION:
TRANSACTION 0 2309, ACTIVE 10 sec, process no 2712, OS thread id 2734320528 inserting, thread declared inside InnoDB 500
mysql tables in use 2, locked 2
4 lock struct(s), heap size 320, 2 row lock(s)
MySQL thread id 2, query id 26 localhost root
insert into a (x, s) select 'y', sleep(10) from dual where not exists(select x from a where x='y')
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 0 page no 60 n bits 72 [b]index `GEN_CLUST_INDEX` of table `test`.`a`[/b] trx id 0 2309 [b]lock mode S[/b]
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
0: len 8; hex 73757072656d756d; asc supremum;;
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 60 n bits 72 index `GEN_CLUST_INDEX` of table `test`.`a` trx id 0 2309 lock_mode X insert intention waiting
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
0: len 8; hex 73757072656d756d; asc supremum;;
*** WE ROLL BACK TRANSACTION (2)