MySQLデータベーストランザクションとその原理

3948 ワード

基本概念
MySQLトランザクションは、主に操作量が多く、複雑度の高いデータの処理に使用されます.
銀行振替は古典的な解釈事務の例である.ユーザAがユーザBに5000元振り替える主なステップは、以下の2つのステップに要約できる.第一に、口座A口座から5000元を差し引く.第二に、口座Bの口座は5000元増加した.この2つのステップは成功するか、すべて成功しないかで、データが一致しません.これにより、異なる銀行間の振り込みであれば、分散トランザクションを使用する必要があることを保証するためにトランザクションが使用されます.
トランザクションのプロパティ(ACID)
(1)MySQLではInnodbデータベースエンジンを使用しているデータベースまたはテーブルのみがトランザクションをサポートします.
(2)トランザクションは、データベースの整合性を維持し、一括SQL文がすべて実行されるか、すべて実行されないかを保証するために使用できます.
(3)トランザクションはinsert,update,delete文を管理するために使用される.
原子性:トランザクションを構成するすべての操作は、論理ユニットであるか、すべて実行するか、すべて実行しないかのいずれかでなければなりません.
≪コンシステンシ|Consistency|emdw≫:トランザクションが開始される前とトランザクションが終了した後、データベースの整合性は破壊されません.これは、書き込まれた資料がすべてのプリセット規則に完全に合致しなければならないことを示します.
独立性:同時トランザクション間では相互に影響しません.
永続性:トランザクションが終了すると、システム障害が発生してもデータの変更は永続的に行われます.トランザクションが正常に実行されたら、すべてディスクに書き込む必要があります.
トランザクション分離の実現原理
データベース・トランザクションでは、ダーティ・リード、重複不可リード、幻読みなどの問題が発生します.
1、汚い読み:事務はまだ提出されていないが、彼の修正は他の事務に見られている.
2、繰り返し不可:1つのトランザクション内でテーブル内の1行のデータが読み込まれ、複数回の読み取り結果が異なる.
3、幻読:同じ事務が突然彼が以前発見しなかったデータを発見した.幻読みは、表に前後に読み込まれたレコードの合計数が異なり、他のトランザクションが挿入したデータが読み込まれます.
トランザクションの分離はロックメカニズムによって実現され、MyISAMとは異なりテーブルレベルのロックを使用し、InnoDBはより微細なローレベルのロックを採用し、データテーブルの性能を向上させた.InnoDBのロックはインデックスをロックすることによって実現され、クエリー条件にプライマリ・キーがある場合はプライマリ・キーをロックし、インデックスがある場合は対応するインデックスをロックしてから対応するプライマリ・キーをロックし(デッドロックの可能性があります)、インデックスさえない場合はデータ・テーブル全体をロックします.
MyISAMタイプでは、トランザクションなどの高度な処理はサポートされておらず、InnoDBタイプではサポートされています.MyISAMタイプのテーブルは、InnoDBタイプよりも実行数が速いが、トランザクションサポートは提供されず、InnoDBはトランザクションサポートや外部キーなどの高度なデータベース機能を提供するパフォーマンスを強調しています.
データベース・ロック
1、悲観ロック(更新が多く、クエリーが少ない場合)悲観ロックを採用すれば.つまり、データベースを操作するときに悲観的な態度を取って、他の人が同時にデータベースにアクセスすると思っています.クエリー文でselect*from account where name=「aaa」for update;排他ロックが加わったのと同じです.Aが残高を照会すると、select money from account where=‘aaa’forupdate;排他ロックを追加し、Bが口座残高を照会する場合、select money from account wherename=‘aaa’forupdate;データベースにもロックをかけるように要求されます.Aはすでにロックを受け取っているため、Bはロックできないので、BはAが実行されるのを待って、ロックを解除してから操作を続けることができます.
2、楽観ロック(更新が少なく、クエリーが多い場合)楽観ロックを採用すると、データベースを操作するときに他のユーザーが同時にアクセスしていないと考えられますが、楽観ロックも完全に楽観的ではありません.楽観ロックはバージョン番号で制御されています.データベース・テーブルにバージョン番号の列があります.データベースから照会するときは、バージョン番号も照会し、更新操作を行うときは、バージョン番号に1を付け、照会条件のバージョン番号は照会したバージョン番号にします.例えば、Aがクエリー操作を実行する場合、selectmoney、version from account where name=‘aaa’;この時点でクエリされたバージョン番号が0であると仮定し、Aは更新操作時にupdate account set money=money+100、version=version+1 where name=‘aaa’and version=0である.コミットされていない場合、Bはクエリに来て、クエリされたバージョン番号は依然として0であり、Bも更新操作update account set money=money+100を実行し、version=version+1 wherename=‘aaa’and version=0を実行する.Aがトランザクションをコミットし、Bがトランザクションをコミットするとバージョン番号0のレコードがないことに気づき、データ損失の問題を回避しました.しかし、この場合、複数のユーザ更新操作が行われた場合、1人のユーザの更新のみが実行される.
3、行レベルのロック(レコードにロックをかける)データベース内のレコードに行レベルのロックをかける場合は、where条件の後にインデックス列が必要です.そうでなければfor updateにはテーブルレベルのロックが追加されます.ロー・レベル・ロックとは、アクセスする現在のローのみをロックし、他のユーザーが他のロー・レコードにアクセスするときにアクセスできます.select * from accountwhere id=1 for update;
4、表レベルのロック(1枚の表にロックをかける)クエリー文の後にfor updateを追加する場合、where条件の後にインデックス列ではない場合、この場合はすべて表レベルのロックです.select * fromaccount where name=‘aaa’ for update;
原子性、一貫性、持続性の実現原理
原子性、安定性、持続性はredoとundoログファイルによって実現され、redoでもundoファイルでもキャッシュがあります.私たちはredoと呼ばれています.bufとundo_buf.同様に、データベースファイルにもdata_というキャッシュがあります.buf.
undoは、トランザクションが開始される前のデータの値を記録し、トランザクションの実行に失敗した場合やROLLBACKの場合、undoレコードの値によってデータを復元できます.
redoログはデータ修正後の値を記録し、トランザクションのコミット前にディスクに書き込む必要を回避し、I/Oを削減します.
取引アクション
BEGIN; //    ,      
insert into t_cart_shopcart (user_id, sku_id, amount, shop_id,  status) values(10001, 10001, 1, 10001, 0);
insert into t_cart_shopcart (user_id, sku_id, amount, shop_id,  status) values(10001, 10002, 1, 10001, 0);
COMMIT; //    ,      
set autocommit = 0; //      
insert into t_cart_shopcart (user_id, sku_id, amount, shop_id,  status) values(10001, 10001, 1, 10001, 0);
insert into t_cart_shopcart (user_id, sku_id, amount, shop_id,  status) values(10001, 10002, 1, 10001, 0);
COMMIT; //    
set autocommit = 1; //