Последствия блокировки таблицы, на которую действуют триггеры? - PullRequest
3 голосов
/ 08 июля 2011

Допустим, у меня есть две таблицы, t1 и t2. У t1 есть триггер, так что при каждой ВСТАВКЕ ВСТАВКА затем происходит на t2.

Если я затем получу блокировку записи на t2, что произойдет, когда я вставлю в t1? Есть несколько вещей, которые мне интересны здесь:

  1. Могу ли я по-прежнему вставлять в t1? Или это заблокирует?

  2. Если я могу просто ВСТАВИТЬ в t1, значит ли это, что триггер будет поставлен в очередь, просто ожидая, пока я разблокирую t2?

  3. Если я вставляю много вещей в t1, пока у меня все еще включена блокировка t2, есть ли какие-нибудь последствия для производительности БД в целом? Будет ли это держать соединения открытыми или что-то подобное?

1 Ответ

2 голосов
/ 08 июля 2011
  1. t1 не будет заблокировано неявно , поскольку документы для объяснения неявной блокировки будут иметь место, если вы выполняете обратное действие (блокировка t1 заблокирует t2
  2. Ошибка MySQL (ОШИБКА 1100 (HY000): таблица t1 не была заблокирована с помощью LOCK TABLES) будет сгенерирована при попытке вставить в t1, поскольку она не была заблокирована, но является местом назначения ее триггераhas.
  3. N / A, запрос на запись в t1 не разрешен движком MySQL.

Однако рассмотрите здесь ваш вариант использования. Если вы просто копируетеВставляет в другую таблицу и не рассчитывает что-либо, вы можете подумать об использовании репликации вместо этого.

Проверено на MySQL 5.1 со следующим SQL из журнала действий игрушки:

DROP TABLE IF EXISTS acts, actions;

CREATE TABLE acts
(
  act_id int unsigned not null auto_increment primary key,
  user_id int unsigned not null
)
ENGINE=innodb;

CREATE TABLE actions
(
  action_id int unsigned not null auto_increment primary key,
  act_id int unsigned not null,
  user_id int unsigned not null
)
ENGINE=innodb;

DELIMITER #

CREATE TRIGGER acts_post_ins_trigger AFTER INSERT ON acts
FOR EACH ROW
BEGIN
  INSERT INTO actions(act_id, user_id) VALUES (new.act_id, new.user_id);
END#

DELIMITER ;

INSERT INTO acts VALUES(1,2);

SELECT * FROM acts;
SELECT * FROM actions;

LOCK TABLE actions WRITE;

SELECT('trying to SELECT acts w/ actions locked...') AS 'SELECT TEST';
SELECT * FROM acts;
SELECT('trying to INSERT into acts w/ actions locked...') AS 'INSERT TEST';
INSERT INTO acts VALUES(3,4);

UNLOCK TABLES;
...