sql >> データベース >  >> RDS >> Mysql

MySQLでのトランザクションの処理

    MySQLは、SQLクエリを処理するためのさまざまなデータベースエンジンを提供します。最も人気のあるエンジンはMyISAMとInnoDBです。これら2つのエンジンのうち、InnoDBはトランザクションをサポートします。つまり、コミットとロールバックを行って、単一のユニットとして複数のクエリを含む操作を実行できます。 MyISAMはトランザクションをサポートしていないため、同じことはできません。 InnoDBは、自動回復にトランザクションログを使用するため、MyISAMと比較して信頼性が高くなります。

    メモ :MyISAMと比較してInnoDBのパフォーマンスがはるかに優れているため、MySQLはMyISAMを完全に削除することを計画しています。

    このチュートリアルでは、START TRANSACTION、 COMMITを使用してMySQLでトランザクションを処理するための詳細を提供します。 、およびロールバック ステートメント。理想的なシナリオであるSQLクエリを個別に実行できますが、場合によっては、タスクに固有のすべてのクエリが成功するか、いずれかのクエリが失敗したために失敗する必要があることを確認する必要があります。このようなタスクは、行を作成、更新、または削除するための複数の操作またはクエリを含む単一のユニットと見なすことができます。したがって、複数の操作を持つトランザクションユニットでは、成功または失敗する必要があります。

    ロールバックできない特定のステートメントがあるため、トランザクションの処理には注意が必要です。これには、CREATE / DROPデータベース、CREATE / ALTER / DROPテーブル、または保存されたルーチンが含まれます。

    トランザクションのプロパティ

    以下に、トランザクションの4つの標準プロパティを示します。これらはACIDとも呼ばれます 。

    アトミシティ -タスクまたはユニットに関連するすべての操作が正常に完了することを保証します。いずれかの操作が失敗した場合は、トランザクションを中止し、以前のすべての操作を以前の状態にロールバックする必要があります。これは、トランザクションが失敗した場合、それに関連する操作が成功してはならないことを意味します。

    一貫性 -データベースが正常にコミットされたトランザクションの変更を反映するように状態を変更することを保証するために、データはトランザクションの開始時と終了時に一貫した状態である必要があります。

    分離 -トランザクションは、他のトランザクションとの中間状態を非表示にして、単独で完了する必要があります。各トランザクションは、互いに独立して透過的に動作する必要があります。

    耐久性 -システム障害が発生した場合でも、トランザクションの一部としてのデータの変更が持続することを保証します。システム障害が発生した場合でも、変更を元に戻してはなりません。

    トランザクションステートメント

    トランザクションの開始 - START TRANSACTIONを使用できます またはBEGIN または作業開始 トランザクションを開始します。 BEGIN または作業開始 STARTTRANSACTIONのエイリアスです。

    コミット -成功した場合は、コミット 変更を永続化するには、トランザクションの最後にコマンドを発行する必要があります。

    ロールバック -障害が発生した場合は、ロールバック トランザクションを開始する前のように状態を復元するには、コマンドを発行する必要があります。

    自動コミットを設定 -ステートメントSETAUTOCOMMITを使用します トランザクションの開始時に自動コミットを無効にし、トランザクションの終了時に有効にします。 トランザクションの開始の場合にのみ使用してください またはBEGIN または作業開始 トランザクションの処理には使用されません。

    送金の例

    同じ銀行内のある口座から別の口座に一定の金額を送金する銀行内送金の例を使用して、取引について説明します。

    メモ :この例はデモンストレーションのみを目的としており、実際のシナリオは銀行のルールに基づいて明らかに異なります。また、トランザクションクエリがプログラムで処理され、中間値が適切な変数に格納されていることも前提としています。

    転送を実行するための操作のシーケンスは次のとおりです。

    • リクエストから借方と貸方の顧客IDを取得し、変数に保存します。
    • リクエストから転送される金額を取得し、変数に保存します。
    • トランザクションを開始します。
    • 最初の顧客のバランスを取り、変数に保存します。
    • 2番目の顧客の残高を取得し、変数に保存します。
    • 最初の顧客の残高が不足している場合は、トランザクションをロールバックします。
    • 最初の顧客アカウントからの控除を反映するために、借方取引を追加します。
    • 障害が発生した場合のロールバック。
    • クレジットトランザクションを追加して、2番目の顧客アカウントへの転送を反映します。
    • 障害が発生した場合のロールバック。
    • 転送を記録します。
    • 障害が発生した場合のロールバック。
    • 最初の顧客の残高を更新します。
    • 障害が発生した場合のロールバック。
    • 2番目の顧客の残高を更新します。
    • 障害が発生した場合のロールバック。
    • トランザクションをコミットします。

    以下は、転送シーケンスを実行するためのサンプルクエリです。

    -- Start the transaction
    START TRANSACTION;

    -- Get balance of first customer
    SELECT balance from ACCOUNT WHERE customer_id = 123124123;

    -- Get balance of second customer
    SELECT balance from ACCOUNT WHERE customer_id = 223124145;

    -- Rollback in case of insufficient funds
    ROLLBACK;

    -- Add debit transaction
    INSERT INTO transaction(customer_id,amount,type,reference) VALUES(123124123, <amount>, 0, <reference>);

    -- Rollback in case of failure
    ROLLBACK;

    -- Add credit transaction
    INSERT INTO transaction(customer_id,amount,type,reference) VALUES(223124145, <amount>, 1, <reference>);

    -- Rollback in case of failure
    ROLLBACK;

    -- Add transfer transaction
    INSERT INTO transfer(from,to,amount) VALUES(123124123, 223124145, <amount>);

    -- Rollback in case of failure
    ROLLBACK;

    -- Update balance of first customer
    UPDATE ACCOUNT SET balance = <balance - amount> WHERE customer_id = 123124123;

    -- Rollback in case of failure
    ROLLBACK;

    -- Update balance of second customer
    UPDATE ACCOUNT SET balance = <balance + amount> WHERE customer_id = 223124145;

    -- Rollback in case of failure
    ROLLBACK;

    -- Commit the transaction
    COMMIT;

    両方の顧客の実際のバランスを反映するために、転送を開始する前に初期状態に戻るためにいずれかの段階で失敗した場合にロールバックする必要があることがはっきりとわかります。

    これが、MySQLでトランザクションを処理する方法です。


    1. T-SQL火曜日#67:新しいバックアップと復元の拡張イベント

    2. 既存のPostgresテーブルを可能な限り透過的にパーティションテーブルに移行するにはどうすればよいですか?

    3. SQLServerで日付範囲を1か月に1行に分割する

    4. MySQLインストールの保護