代码之家  ›  专栏  ›  技术社区  ›  theyletmehavecontrol

从触发器函数更新Postgres时的死锁

  •  0
  • theyletmehavecontrol  · 技术社区  · 10 年前

    我运行的是postgres 9.4。我有一个事件表,其中每一行代表一个事件,该事件具有指定用户的名称。

    event id (primary key)
    event name
    user_id (foreign key in users table)
    

    我有一个触发器函数,它检查事件的名称,如果它与某些名称匹配,则将一些数据添加到用户表中的列中,以查找匹配的user_id。

    然而,我遇到了死锁错误——我认为这是由于我指定函数的方式造成的。有人能建议如何构造函数以避免错误吗?

    BEGIN
    
    IF NEW.name = 'labvar1' THEN
        UPDATE users SET labvar1=new.name WHERE new.user_id = users.user_id;
        UPDATE users SET labvar1_properties=new.properties WHERE new.user_id = users.user_id;
    
    ELSIF NEW.name = 'labvar2' THEN
        UPDATE users SET labvar2=new.name WHERE new.user_id = users.user_id;
        UPDATE users SET labvar2_properties=new.properties WHERE new.user_id = users.user_id;
    
    ELSIF NEW.name = 'labvar3' THEN
        UPDATE users SET labvar3=new.name WHERE new.user_id = users.user_id;
        UPDATE users SET labvar3_properties=new.properties WHERE new.user_id = users.user_id;
    
    ELSIF NEW.name = 'labvar4' THEN
        UPDATE users SET labvar4=new.name WHERE new.user_id = users.user_id;
        UPDATE users SET labvar4_properties=new.properties WHERE new.user_id = users.user_id;
    
    ELSIF NEW.name = 'labvar5' THEN
        UPDATE users SET labvar5=new.name WHERE new.user_id = users.user_id;
        UPDATE users SET labvar5_properties=new.properties WHERE new.user_id = users.user_id;
    
    ELSE
    RETURN null;
    END IF;
    RETURN NEW;
    END;
    

    感谢任何帮助!

    1 回复  |  直到 10 年前
        1
  •  0
  •   Kamil Gosciminski    10 年前

    死锁意味着您有两个事务相互锁定。

    阅读 deadlocks 以及手册中为什么会出现这种情况。


    为了更新表中的两列,不需要运行两个单独的语句。您可以将其组合在一个语句中,如下所示:

    UPDATE users 
      SET labvar1 = NEW.name, 
          labvar1_properties = NEW.properties 
    WHERE user_id = NEW.user_id