MySQL(5)トランザクション

6061 ワード

取引
MySQLでInnoDBストレージエンジンがトランザクションをサポート
トランザクション(Transaction)とは、単一の論理ワークユニットとして実行される一連の操作を指し、完全に一緒に実行し、データベースに作用し、データベースを永遠に修正することを指す.完全に実行しないか、データベースを変更しません.
たとえば、銀行間の送金操作は、データベース上で3ステップで完了します.(1)ソース・アカウント減少保管金額(2)ターゲット・アカウント増加金額(3)トランザクション・ログにトランザクション全体を記録するとトランザクションとみなされ、操作に失敗するとトランザクションはすべてロールバックされ、すべてのトランザクションの操作は取り消されます.操作が成功した場合は、データベースを永続的に変更します.
トランザクションのプロパティACID
アトミック(Atomicity)トランザクションはアトミックワークユニットでなければなりません.データの変更は、すべて実行するか、すべて実行しないかのいずれかです.
コンシステンシトランザクションは、完了時にすべてのデータをコンシステンシ状態に保つ必要があります.物事が完成してからすべての使用者に見られるようになり、データの完全性が保証されます.例えば口座Aから口座Bにお金が振り込まれ、口座Aのお金が減少して口座Bのお金が増加していない場合、データが一致しない状態にあると考えられます.
独立性(Insulation)同時事務所による修正は、他の同時事務所による修正と独立しなければならない.つまり、トランザクション・オペレーションのデータは他の実物に表示されず、オペレーションされません.
永続性(Durability)トランザクションが完了すると、システムへの影響は永続的になります.この変更は、致命的なシステム障害が発生しても維持されます.
トランザクションのパターンタイプ
START TRANSACTIONでトランザクションCOMMITを開始し、変更されたデータを永続的に保持するROLLBACKですべての変更を取り消すことができます.
MySQLはオートコミット(AUTOMMIT)モードを採用しています.すなわち、1つのトランザクションが表示されずに開始されると、増加、削除、変更ごとに1つのトランザクションとしてコミット操作が実行される
サンプル
START TRANSACTION;
SELECT balance FROM checking WHERE customer_id =1000;
UPDATE checking SET balance = balance -200.00 WHERE customer_id = 1000;
UPDATE saving SET balance = balance + 200.00 WHERE customer_id = 1000;
COMMIT;

COMMIT AND CHAINは実物を提出してから新しい事務を再開したと表明した.
START TRANSACTION;
...
(    )
...
COMMIT AND CHAIN;
--             
...
(    )
...
COMMIT;

セーブポイントビジネスロジックが複雑な場合があるため、ビジネスを実現するには多くの操作が必要です.失敗するたびにすべてのデータがロールバックされないように、トランザクションのセーブポイントを選択できます.
SET AUTOCOMMIT =0;
--        1      0    。
INSERT INTO userinfo VALUES(6'test1');
savepoint s1;
INSERT INTO userinfo VALUES (7,'test2');
savepoint s2;
INSERT INOT userinfo VALUES (8,'test3');
savepoint s3;

3つの挿入文を実行し、最初にロールバックしたい場合は、ROLLBACKが最初の状態にロールバックし、savepoint s 1の状態(test 1を挿入する)rollback to savepoint s 1にロールバックすればよい.
コンカレントコントロール
データに同時アクセスする場合、制御を行わないと、変更されたデータは、同じデータの読み取りまたは変更に同意した他のユーザに影響を及ぼす可能性があります.まず、トランザクションの独立性を考慮しないと、いくつかの問題が発生します.
(1)ダーティリードダーティリードとは、あるトランザクション処理中に別のコミットされていないトランザクションのデータが読み込まれたことを意味する.
たとえば、トランザクションAはデータベース内のローデータを変更しています.変更中にトランザクションBはローデータを読み込み、次の操作の準備を保持します.しかし、この時点で事務Aは自分が修正したのは事務が正確ではないと判断し、ROLLBACKになった.この場合、トランザクションBは、実際には存在しないデータ(ダーティデータ)を読み出す.
解決方法:Aトランザクションが実物をコミットする前に、他のトランザクションが変更中のデータを読み取ることは許されません.
(2)繰り返し不可繰り返し不可繰り返し不可とは、データベース内のあるデータに対して、1つのトランザクション範囲内で複数のクエリが異なるデータ値を返したことを意味します.これは、クエリ間隔で別のトランザクションによって変更され、コミットされたためです.
たとえば、トランザクションAがあるデータを読み込んでいるのに対し、トランザクションBがそのデータをすぐに修正してデータベースにコミットすると、トランザクションAが再びそのデータを読み込んで異なる結果を得て、重複しない読み取りを送信します.
重複しない読み取りと汚い読み取りの違いは、あるトランザクションが別のトランザクションでコミットされていない汚いデータを読み取り、重複しない読み取りは前のトランザクションでコミットされたデータを読み取ることです.
解決方法:トランザクションAが最後のデータの読み取りを完了するまで、他のトランザクションが読み取り中のデータを変更することは許可されません.
(3)幻読幻読は,トランザクションが独立して実行されない場合に発生する現象である.たとえば、トランザクションAがテーブル内のすべてのローのデータ・アイテムを1から2に変更すると、トランザクションBはテーブルにデータ・アイテムを挿入し、そのデータ・アイテムの数値は1であり、データベースにコミットします.一方,トランザクションAを操作するユーザは,変更したばかりのデータを再確認すると,もう1行が変更されていないことに気づくが,この行はトランザクションBから追加され,幻覚を起こすように幻読みが発生している.
幻読と重複不可読は、もう1つのコミットされたトランザクション(この点ではダーティリードが異なります)を読み取り、重複不可クエリーは同じデータ項目であり、幻読はデータ全体(データの個数など)を対象としています.
MySQLデータベースが提供する4つの独立性レベルを見てみましょう.
①Serializable(シリアル化):汚れ読み、繰り返し読み、幻読みの発生を避けることができます.シリアル化は、読み込まれた各ローのデータにロックをかけるため、ロックのタイムアウトとロックの占有量の問題を引き起こし、厳格なデータ整合性が要求されない限り、実際のビジネスではあまり使用されません.
②Repeatable read(繰り返し読み可能):汚読み、再読み不可の発生を避けることができる.
③Read committed(既読提出):汚読の発生を避けることができる.
④Read uncommitted(リードコミットなし):最低レベルで、いかなる状況でも保証できない.
以上の4つの独立性レベルが最も高いのはSerializableレベルで、最も低いのはRead uncommittedレベルで、もちろんレベルが高いほど実行効率が低下します.Serializableのようなレベルは、Javaマルチスレッドのロックのようにテーブルをロックすることで、他のスレッドはロック外でしか待つことができないので、普段どの独立性レベルを選択するかは実際の状況によって異なります.MySQLデータベースinnodbでは、デフォルトの独立性レベルはRepeatable read(繰り返し可能)です.
現在の独立性レベルの表示
select @@tx_isolation;

トランザクションの独立性レベルの設定
set  [glogal | session]  transaction isolation level       ;

set tx_isolation='      ';