Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 锁定通过触发器作用的表的后果?_Mysql_Sql_Database_Triggers_Locking - Fatal编程技术网

Mysql 锁定通过触发器作用的表的后果?

Mysql 锁定通过触发器作用的表的后果?,mysql,sql,database,triggers,locking,Mysql,Sql,Database,Triggers,Locking,假设我有两个表,t1和t2t1上有一个触发器,因此每次插入时都会在t2上进行插入 如果我随后在t2上获得写锁,当我插入t1时会发生什么?这里有一些事情我很好奇: 我仍然可以插入到t1?还是会锁上 如果我可以插入t1很好,这是否意味着触发器将排队等待,直到我解锁t2 如果我在t1中插入了很多东西,而我仍然锁定了t2,那么对数据库的整体性能有什么影响吗?这会保持连接打开还是类似的 t1将不会是,因为隐式锁定的文档解释的情况是,如果您执行相反的操作(锁定t1将锁定t2 尝试插入到t1时将生成MySQL

假设我有两个表,
t1
t2
t1
上有一个触发器,因此每次插入时都会在
t2
上进行插入

如果我随后在
t2
上获得写锁,当我插入
t1
时会发生什么?这里有一些事情我很好奇:

  • 我仍然可以插入到
    t1
    ?还是会锁上

  • 如果我可以插入
    t1
    很好,这是否意味着触发器将排队等待,直到我解锁
    t2

  • 如果我在
    t1
    中插入了很多东西,而我仍然锁定了
    t2
    ,那么对数据库的整体性能有什么影响吗?这会保持连接打开还是类似的

  • t1
    将不会是,因为隐式锁定的文档解释的情况是,如果您执行相反的操作(锁定
    t1
    将锁定
    t2
  • 尝试插入到
    t1
    时将生成MySQL错误(错误1100(HY000):表
    t1
    未使用锁表锁定),因为它尚未锁定,但其触发器的目标已锁定
  • 不适用,MySQL引擎不允许向
    t1
    写入查询
  • 请考虑您的用例。如果您只是简单地将插入复制到另一个表中,而不计算某些内容,则可能需要考虑使用复制。

    在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;
    

    谢谢,Shelhamer。我阅读了关于隐式锁的文档,但我的印象是,它们讨论的是锁定表的触发器,而不是与锁定表交互的其他表上的触发器。如你所说,如果是源或目标是否被锁定,这是有信息的。我的用例实际上更像com比此复杂(使用此方法在生产中更改表),但该通知在一般情况下很受欢迎。我在这里的一个大型MySQL/PHP网站上从内存中发言,并没有重新测试,但我相信它是正确的。如果我有时间在午餐时验证,我会让你知道的。@umbrae,我刚刚在DB中测试了这一点,我的原始答案实际上是正确的:将抛出一个MySQL错误原因触发器中涉及的表尚未全部锁定。隐式锁定仅在作为触发器源的表被锁定时才会发生。谢谢Shelhamer。如果您手头有测试脚本,我相信我和任何其他看到此脚本的人都希望看到它!我添加了用于测试的sql,以便您可以验证错误行为。