推奨 (無料): mysql ビデオ チュートリアル
トランザクションの分離Property
MySQL はクライアント/サーバー アーキテクチャ ソフトウェアです。同じサーバーに対して、複数のクライアントが接続できます。各クライアントがサーバーに接続された後、それをセッションと呼びます。各クライアントは、独自のセッションでサーバーにリクエスト ステートメントを発行できます。リクエスト ステートメントはトランザクションの一部である場合があります。つまり、サーバーは複数のトランザクションを同時に処理する場合があります。データベース上で複数のトランザクションが同時に実行されると、ダーティリード、ノンリピータブルリード、ファントムリードなどの問題が発生することがあります。これらの問題を解決するために「分離レベル」という概念があります。
理論的には、トランザクションが特定のデータにアクセスする場合、他のトランザクションはキューに入れられる必要があります。トランザクションが送信された後でのみ、他のトランザクションはデータにアクセスし続けることができます。しかし、一般的に言えば、絶縁が厳しくなるほど効率は低下します。したがって、多くの場合、分離と効率の間のバランスを見つける必要があります。
同時トランザクション実行で発生する問題
ダーティ リード: ダーティ リードとは、あるトランザクションが、そのトランザクションによって変更されたコミットされていない別のデータを読み取ることを意味します。
たとえば、Xiao Wang の口座の残高が 100 の場合、Xiao Wang の口座にアクセスするには 2 つのトランザクションが必要になります。
# セッション A | セッション B |
---|---|
begin; | |
##selectbalance from xxx where client_no = 'Xiao Wang クライアント番号' ; (150 と表示された場合は、ダーティ リードが発生したことを意味します) |
| rollback;
非反復読み取り:
非反復読み取りとは、同じトランザクション内で同じデータ セットを複数回読み取ることを指しますが、結果は異なります。反復不可能な読み取りは、クエリされたデータが複数の検索中に他のトランザクションによって変更されたために発生します。次の 2 つのセッション リクエストを見てください。
#クライアント番号 = 'Xiao Wang 顧客番号' の xxx から残高を選択 ; (残高は 100 であると読み取ります) |
|
#更新 xxx 残高 = 残高 50 を更新 ここで client_no = 'Xiao Wang クライアント番号' ; | |
##commit; | |
selectbalance from xxx where client_no = 'Xiao Wang クライアント番号' ; (150 と表示された場合は、反復不可能な読み取りが発生したことを意味します) ) |
|
コミット; |
|
セッション中A の同じトランザクション内で、2 つの同一のクエリの結果が異なります。これは、反復不可能な読み取りが発生したことを意味します。 |
# セッション A
セッション B
##begin; | |||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
begin; |
|
||||||||||||||||||||
insert into xxx(client_no,name,balance) value('Xiao Zhang 顧客番号','Xiao Zhang',100); |
|||||||||||||||||||||
#commit; |
select name from xxx Balance where = 100; | ||||||||||||||||||||
#コミット; | |||||||||||||||||||||
セッションの 2 番目のクエリトランザクションで、最初のクエリでは見つからなかった名前「Xiao Zhang」が見つかりました。これは、ファントム読み取りが発生したことを意味します。 SQL 標準によって確立された 4 つの分離レベル ISO および ANIS SQL 標準では、次の 4 つのトランザクション分離レベルが確立されています。コミット済み (コミットされた読み取り)、反復可能読み取り (反復可能読み取り)、およびシリアライズ可能 (シリアル化可能)。 まず、これら 4 つの分離レベルの意味を見てみましょう。
SQL 標準では、分離レベルが異なると、同時トランザクションによってさまざまな重大度の問題が発生する可能性があると規定されています。具体的な状況は次のとおりです:
ISO および ANIS SQL 標準では 4 つのトランザクション分離レベルが規定されていますが、すべてのデータベース ベンダーがこれに従っているわけではありません。たとえば、Oracle データベースは、コミットされていない読み取り (コミットされていない読み取り) および反復可能な読み取り (反復可能な読み取り) トランザクション分離レベルをサポートしていません。 MySQL InnoDB ストレージ エンジンは 4 つの分離レベルをサポートしますが、SQL 標準で定義されているものとは異なります。 InnoDB ストレージ エンジンは、デフォルトの反復読み取り (反復読み取り) トランザクション分離レベル - Key Lock ロックで Next を使用します。アルゴリズムにより、ファントム読み取り の発生が回避されます。言い換えれば、InnoDB ストレージ エンジンは、反復読み取りのトランザクション分離レベルの下でトランザクションの分離要件を完全に保証できます。つまり、SQL 標準のシリアル化可能な分離レベル要件に達しています。 InnoDB ストレージ エンジンでは、次のコマンドを使用して、グローバルまたは現在のセッションのトランザクション分離レベルを設定できます。 SET [GLOBAL|SESSION] TRANSACTION ISOLATION LEVEL{ READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE} ログイン後にコピー 現在のセッションの分離レベルを読み取りコミットに設定したい場合は、次のステートメントを使用できます。 SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; ログイン後にコピー トランザクションのデフォルトの分離レベルを設定したい場合は、 MySQL データベースが起動されると、設定ファイル内のトランザクションを変更する必要があります。分離の値、たとえば、起動前に transaction-isolation = READ COMMITTED を指定した場合、デフォルトの分離レベルは、トランザクションは元の REPEATABLE READ から READ COMMITTED に変更されます。 SELECT @@transaction_isolation; ログイン後にコピー グローバル トランザクション分離レベルを表示するには、次のステートメントを使用できます: SELECT @@global.transaction_isolation; ログイン後にコピー プログラミング関連の知識について詳しくは、 プログラミング ビデオ |
以上がMySQL トランザクション分離レベルとダーティ リード、ファントム リード、非反復読み取りの例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。