3

トリガーは次のとおりです。

DELIMITER //
CREATE TRIGGER `Conturi_BI` BEFORE INSERT ON `Conturi` FOR EACH ROW BEGIN
SET NEW.CUI_cod = digits(NEW.CUI);
END//
DELIMITER ;

照合と重複検索を高速化するために、ユーザー入力に数字関数を適用しているだけですが、それを実装して以来、一部のインサートがハングします。更新用に同様のものを作成しましたが、同じ問題はありません。

数字関数は私が作成したもので、トリガーと挿入はほとんどの場合正常に機能します。

要求に応じて、数字は機能します。

BEGIN
  DECLARE i, len SMALLINT DEFAULT 1;
  DECLARE ret CHAR(32) DEFAULT '';
  DECLARE c CHAR(1);
  SET len = CHAR_LENGTH( str );
  REPEAT
    BEGIN
      SET c = MID( str, i, 1 );
      IF c BETWEEN '0' AND '9' THEN 
        SET ret=CONCAT(ret,c);
      END IF;
      SET i = i + 1;
      END;
  UNTIL i > len END REPEAT;
  RETURN ret;
END
4

2 に答える 2

2

関数に渡すと、関数は機能しませdigitnull。永遠にループします。で試してみてください

select digits(null)

したがって、毎回NEW.CUInull になると、挿入がハングします。null関数の先頭にチェックを追加できます。

if str is null
then 
   return '';
end if;
于 2012-10-22T16:22:26.083 に答える
1

私の最善の推測は、これはあなたの「いくつかの」ステートメントから判断すると、ロックの競合で問題が発生することです。

私があなたのトリガーを正しく理解していれば、テーブル A への書き込みで (実際には前に) プロシージャーをトリガーし、書き込み対象の同じテーブル A 内のすべてのレコードを変更し、単一のトランザクション内のすべての行を排他的にロックします。

別のトランザクション中にこれを行うと、トリガーがロックのアップグレードを待機し、他のトランザクションがロックのアップグレードを待機するデッドロック状況につながる可能性があります (一言で言えばデッドロックです)。

この取り組みの成功は、少なくともデータベース ドライバの実装にかかっています。行をロックし、トリガーされたトランザクションで再度ロックすると、ほとんどのデータベース ドライバーは、トランザクションを拡張できると想定しますが、一部のデータベースでは、トランザクションが同じ接続からのものであることを認識できず、それらを個別に処理できません。

于 2012-10-22T13:06:26.530 に答える