0

私は php/MySQLi ベースのサイトを開発しています。複雑な手順の実行中に何らかの理由でページがクラッシュした場合にどうなるかについて質問があります。

例:

if (get_message_call)
{
    add something to table 1
    add something to table 2
    add something to table 3   ( based on some values inserted into table2 ) 
    add something to table 4
    etc...
}

PHPmyAdmin (InnoDB) を使用してデータベースを構築しました。ただし、主キー/外部キーが理論どおりに機能しなかったため、リレーションを割り当てていません (おそらく、私はそれを間違って書きました)。

私の主な懸念は、何らかの理由でステートメントが中止された場合 (ページのクラッシュ、接続の緩みなど)、「table3 に何かを追加」を実行しているとしましょう。最初と 2 番目のステートメントが実行され、残りは実行されないと思いますか?

他のテーブルのキーなどを台無しにする可能性があるため、これが発生しないようにする最善の方法は何ですか..説明が少し曖昧かもしれませんが、誰かが私の主張を理解してくれることを願っています.

「ストアド プロシージャとトリガーでのロールバックとコミット」について読んだことがありますが、正しく理解できたかどうかはわかりません..

前もって感謝します。

4

2 に答える 2

1

InnoDBの場合は、この種の挿入にトランザクションを使用する必要があります。詳細については、以下を参照してください。

于 2012-10-10T10:28:39.010 に答える
0

これは、データベース トランザクションを使用する必要がある場合です。複数のテーブルを更新する必要があり、その更新が以前の更新に依存している場合は、コードをデータベースのストアド プロシージャに配置するのが最も安全です。ストアド プロシージャはトランザクションを開始できます。トランザクションは、正しく終了した場合にのみデータをデータベースにコミットします (つまり、1 つのテーブルに書き込み、2 番目のテーブルに書き込むと、3 番目の書き込みが失敗し、1 番目と 2 番目の書き込みが失敗します)。もロールバックされます)。

次に例を示します。ストアド プロシージャは 3 つの入力引数を取り、2 つの出力値を返し、3 つのテーブルを更新します。エラーが発生した場合、トランザクションはロールバックされます。(これは単なる例であり、軽微な構文エラーがある可能性があることに注意してください)

CREATE DEFINER=`root`@`localhost` PROCEDURE `doSomething`(
  IN input1 INT,
  IN input2 VARCHAR(255),
  IN input3 VARCHAR(100),
  OUT output1 INT,
  OUT output2 INT
)
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; END;
DECLARE EXIT HANDLER FOR SQLWARNING BEGIN ROLLBACK; END;
DECLARE EXIT HANDLER FOR NOT FOUND BEGIN ROLLBACK; END;

START TRANSACTION;

INSERT INTO table1 (column1, column2, column3) VALUES (input1, input2, NOW());
SET @new_row_id = LAST_INSERT_ID();


INSERT INTO table2 (column1, colum2) VALUES (@new_row_id, input3);
SET @other_new_row_id = LAST_INSERT_ID();

UPDATE table3 SET mycolumn = @other_new_row_id WHERE id = @new_row_id;

COMMIT;

SET output1 = @new_row_id;
SET output2 = @other_new_row_id;

END
于 2012-10-10T10:43:46.797 に答える