データベーストランザクションのACIDプロパティ、データベースの同時実行性の問題、および4つの分離レベル

データベーストランザクションのACIDプロパティ、データベースの同時実行性の問題、および4つの分離レベル

データベーストランザクション

データベーストランザクションは、データをある状態から別の状態に変換する論理演算ユニットのセットです。

論理操作ユニットのセット; 1つ以上のDML操作

トランザクション処理の原則

すべてのトランザクションが作業単位として実行されるようにします。障害が発生した場合でも、この実行方法を変更することはできません。
トランザクションが複数の操作を実行する場合、すべてのトランザクションがコミットされてから永続的に保存されるか、すべての変更が破棄され、トランザクション全体が元の状態にロールバックされます。

データが送信されると、ロールバックすることはできません

これらのアクションにより、自動送信が行われます

DDL操作が実行されると、
DMLが自動的に送信されます。デフォルトでは、実行されると自動的に送信さ
れます。autocommit= falseを設定すると、DML自動コミットをキャンセルできます。
デフォルトでは、データは次の場合に自動的に送信されます接続が閉じられます。

ACID属性

トランザクションは、原子性、一貫性、分離、および耐久性の4つの属性、つまりACIDの4つの属性を満たす必要があります。

アトミシティ

トランザクションは不可分な全体です。トランザクションの全体的な目標を確実にするために、トランザクションはアトミックである必要があります。つまり、データが変更されると、すべてが実行されるか、まったく実行されません。つまり、トランザクションを部分的に完了することは許可されておらず、これらの操作の一部のみを実行することによって発生するエラーを回避できます。

一貫性

トランザクションが実行される前後で、データベースデータは一貫している必要があります。データベースの整合性状態は、モードロックで指定された制約を満たす必要があるため、トランザクションが完全に実行された後も、データベースは整合性のある状態のままです。

例:銀行振込の場合、振込の前後の2つの口座の合計は変更されません。

隔離

並行会社によって行われた変更は、他の並行会社によって行われた変更から分離する必要があります。トランザクションがデータベースを表示するときのデータの状態は、別の並行トランザクションがデータベースを変更する前の状態、または別のトランザクションがデータベースを変更した後の状態のいずれかです。トランザクションは、中間状態のデータを表示しません。

例:トランザクションT1とT2の任意のペアの場合、T1の場合、T2はT1が開始する前に終了するか、T1が終了した後に実行を開始します。

持久性

永続的とも呼ばれます。トランザクションが完了した後、DBMS(データベース管理システム)はデータベース内のデータの変更が永続的であることを保証します。システムまたはメディアに障害が発生した場合、変更も永続的に維持されます。耐久性は通常、データベースのバックアップとリカバリによって保証されます。

  • 注厳密に言えば、データベーストランザクション属性はデータベース管理システムによって保証されます。アプリケーション全体の操作中に、アプリケーションはデータベースのACID実装を考慮する必要はありません。

通常の状況では、トランザクションはCOMMIT(コミット)またはROLLBACK(ロールバック)ステートメントを実行することによって終了します。COMMITステートメントが実行されると、トランザクションの開始以降にデータベースに加えられたすべての変更が永続的になります。つまり、ディスクに書き込まれます。ROLLBACKステートメントが実行されると、トランザクションの開始以降にデータベースに加えられたすべての変更が永続的になります。元に戻すになり、データベースの内容はトランザクションが開始される前の状態に戻ります。いずれの場合も、トランザクションが完了すると、一貫した状態に戻ることが保証されます。

データベースの同時実行性の問題

ロックがなく、複数のユーザーが同時にデータベースにアクセスする場合、トランザクションが同じデータを同時に使用すると問題が発生する可能性があります。同時操作によって引き起こされるデータの不整合には、データの更新の損失、「ダーティ」データの読み取り(ダーティ読み取り)、および繰り返し不可能な読み取りが含まれます。

更新が失われました

  • 両方のトランザクションが同時にデータの行を更新し、一方のトランザクションによるデータの更新は、もう一方のトランザクションによるデータの更新を上書きします。これは、システムがロック操作を実行しないため、同時実行性が分離されないためです。

ダーティリード

  • トランザクションは、別のトランザクションのコミットされていないデータ操作の結果を読み取ります。すべての操作がロールバックされる可能性があるため、これは非常に危険です。

繰り返し不可

  • 繰り返し不可の読み取り:トランザクションは同じ行のデータを2回読み取りますが、結果は異なります。

次の状況を含みます。

  • ダミー読み取り:トランザクションT1が特定のデータを読み取った後、トランザクションT2がそのデータを変更し、トランザクションT1がデータを再度読み取ると、前回とは異なる値を取得します。
  • ファントム読み取り:トランザクションは、操作中に2つのクエリを実行します.2番目のクエリの結果には、最初のクエリに表示されなかったデータが含まれているか、最初のクエリに表示されたデータがありません。これは、2つのクエリ中にデータを挿入する別のトランザクションが原因で発生します。

データベーストランザクションの4つの分離レベル

データベーストランザクションには、低から高までの4つの分離レベルがあり、コミットされていない読み取り、コミットされた読み取り、繰り返し可能な読み取り、およびシリアル化可能です。これらの4つのレベルは、ダーティ読み取り、繰り返し不可能な読み取り、およびファントム読み取りの問題を1つずつ解決できます。 。
分離レベルが異なれば、トランザクションの処理も異なります。

  • コミットされていない読み取り:失われた更新のみを処理します。トランザクションがデータの書き込みを開始した場合、他のトランザクションは同時に書き込むことはできませんが、他のトランザクションはこのデータ行を読み取ることができます。これは「排他的書き込みロック」によって実現できます。
  • コミットされたデータの読み取り(コミットされた読み取り):失われた更新とダーティな読み取りに対処します。データを読み取るトランザクションは、他のトランザクションが変更された行データにアクセスし続けることを許可しますが、コミットされていない書き込みトランザクションは、他のトランザクションが変更された行にアクセスすることを禁止します。これは、「インスタント共有読み取りロック」と「排他的書き込みロック」によって実現できます。
  • 繰り返し可能な読み取り(繰り返し可能な読み取り):失われた更新、ダーティな読み取り、および繰り返し不可能な読み取りを処理します。データを読み取るトランザクションは書き込みトランザクションを禁止しますが、読み取りトランザクションは許可され、書き込みトランザクションは他のトランザクションを禁止します。「共有読み取りロック」と「排他的書き込みロック」で実現できます。
  • シリアル化(Serializable):厳密なトランザクション分離を提供します。シリアル化の実行を失う必要があります。トランザクションは次々にしか実行できず、同時に実行することはできません。トランザクションのシリアル化は「行レベルのロック」だけでは実現できません。クエリ操作を実行したばかりのトランザクションが新しく挿入されたデータにアクセスしないようにするには、他のメカニズムを使用する必要があります。

分離レベルが高いほど、データの整合性と統一性が保証されますが、同時パフォーマンスへの影響は大きくなります。ほとんどのアプリケーションでは、最初にデータベースシステムの分離レベルをReadCommittedに設定することを検討できます。ダーティリードを回避でき、優れた同時実行パフォーマンスを備えています。繰り返し不可能な読み取り、ファントム読み取り、2番目のタイプの失われた更新などの同時実行の問題が発生する可能性がありますが、アプリケーションはペシミスティックロックまたはオプティミスティックロックを使用して、このような問題が発生する可能性のある個々の機会を制御できます。

  • Oracleは、READ COMMITED、SERIALIZABLEの2つのトランザクション分離レベルをサポートしています。Oracleのデフォルトのトランザクション分離レベルは、READCOMMITEDです。
  • Mysqlは4つのトランザクション分離レベルをサポートしています。Mysqlのデフォルトのトランザクション分離レベルは次のとおりです。REPEATABLEREAD

トランザクション分離レベルの設定

//查看当前事物级别:
SELECT @@tx_isolation;
//设置mysql的隔离级别:
//set session transaction isolation level 设置事务隔离级别

//设置read uncommitted级别:
set session transaction isolation level read uncommitted;

//设置read committed级别:
set session transaction isolation level read committed;

//设置repeatable read级别:
set session transaction isolation level repeatable read;

//设置serializable级别:
set session transaction isolation level serializable;

分離レベルを取得および設定するためのJavaコード(以下の接続はConnectionオブジェクトであり、特定の実装は編成されません)

//获取数据库事务隔离级别
int transactionIsolation = conn.getTransactionIsolation();
//设置数据库事务隔离级别;事务隔离级别:TRANSACTION_READ_COMMITTED
conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);

おすすめ

転載: blog.csdn.net/qq_46388795/article/details/114452454