1

ネストされたセットの形式で mysql に階層データを格納しています。

myTable
  id,
  title,
  lft,
  rgt

次の一連の SQL ステートメントを使用して、新しいノードを挿入します。

SELECT @myLeft := lft FROM myTable WHERE ID = $id;  
UPDATE myTable SET rgt = rgt + 2 WHERE rgt > @myLeft;       
UPDATE myTable SET lft = lft + 2 WHERE lft > @myLeft;       
INSERT INTO myTable(title, lft, rgt) VALUES($title, @myLeft + 1, @myLeft + 2);

これは機能しますが、多数のノードが (近くで) 同時に追加されると、問題が発生する可能性があります。

データが破損しないようにする最善の方法は何ですか (ストアド プロシージャはオプションではありません)。この sql をトランザクションに含めるだけで十分ですか? トランザクションとテーブル ロックを使用する必要がありますか?

ありがとう

4

1 に答える 1

1

MyISAM テーブルを使用している場合、MyISAM テーブルはトランザクションをサポートしていないため、テーブルをロックする必要があります。

InnoDB テーブルの場合、すべての作業を 1 つのトランザクションで実行できます。

BEGIN; -- or whatever API your framework has for starting a transaction
SELECT @myLeft := lft FROM myTable WHERE ID = $id FOR UPDATE;  
UPDATE myTable SET rgt = rgt + 2 WHERE rgt > @myLeft;       
UPDATE myTable SET lft = lft + 2 WHERE lft > @myLeft;       
INSERT INTO myTable(title, lft, rgt) VALUES($title, @myLeft + 1, @myLeft + 2);
COMMIT; -- or whatever API your framework has for commiting a transaction
于 2010-06-27T22:00:41.817 に答える