1

私は次の設定をしています:

次のようなクエリ:

  "INSERT INTO table (c1, c2,...) values (v01, v02,...), (v11, v12,...)..."

テーブルには、自動インクリメントの主キーがあります。挿入された各行のインデックスを知る必要があります。

これを行う 1 つの方法は、最後の行のインデックスを取得することです。挿入されるインデックスは、lastRowIndex - nrRows から lastRowIndex までです。

私の問題/不確実性は次のとおりです。同じテーブルに行を挿入するこの挿入と並行して別の挿入が実行された場合(たとえば、別のユーザーが同じ関数を呼び出します)、それらの間に行を挿入する可能性はありますか(どんなに小さくても)前に述べたクエリによって生成された?繰り返しますが...非常に重要です(理由は明らかです... ids構造を殺します)それは起こらないので、確認する必要があります。

または、何らかの理由で ID が連続しない可能性があります。

4

1 に答える 1

1

実行中の 2 つのトランザクションがあり、それぞれが列を持つテーブルに行を挿入するとしAUTO_INCREMENTます。1 つのトランザクションはINSERT ... SELECT1000 行を挿入するステートメントを使用しており、別のトランザクションはINSERT1 行を挿入する単純なステートメントを使用しています。

Tx1: INSERT INTO t1 (c2) SELECT 1000 rows from another table ...
Tx2: INSERT INTO t1 (c2) VALUES ('xxx');

SELECTInnoDB は、 のINSERTステートメントでから取得される行数を事前に知ることができずTx1、ステートメントが進むにつれて自動インクリメント値を一度に 1 つずつ割り当てます。ステートメントの最後まで保持されるテーブル レベルのロックでは、INSERTテーブル t1 を参照するステートメントは一度に 1 つしか実行できず、異なるステートメントによる自動インクリメント番号の生成はインターリーブされません。ステートメントによって生成される自動インクリメント値は連続し、 のステートメントでTx1 INSERT ... SELECT使用される (単一の) 自動インクリメント値は、どのステートメントが最初に実行されるかに応じて、 で使用されるすべての値よりも小さいか大きいかのいずれかになります。INSERTTx2Tx1

SQL ステートメントがバイナリ ログから再生されたときに同じ順序で実行される限り (ステートメント ベースのレプリケーションを使用する場合、または回復シナリオで)、結果は最初に実行されたときTx1と同じになります。Tx2したがって、ステートメントの最後まで保持されるテーブル レベルのロックは、INSERT自動インクリメントを使用するステートメントを、ステートメント ベースのレプリケーションで安全に使用できるようにします。ただし、これらのロックは、複数のトランザクションが同時に挿入ステートメントを実行している場合、同時実行性とスケーラビリティを制限します。

参照

于 2013-03-15T13:39:00.333 に答える