以下のMYSQLプロシージャ(正確な引数は言及されていません)を使用して、データを3つのテーブル「T1」、「T2」、および「T3」に挿入しています。
CREATE DEFINER=`root`@`%` PROCEDURE `insert_values`(v1,v2,v3,v4,v5,v6.......)
begin
declare max_id bigint;
start transaction;
insert ignore into T1
fields(.....)
values
(v1,v2,v3,.......);
insert ignore into T2
fields(......)
values
(v1,v4,..........);
If (v3 <> '') Then
set @max_id:=(select max(id) from T1);
insert ignore into T3
fields(.......)
values
(@max_id,v3,v5,v6,........);
End If;
commit;
end
テーブル T1 と T2 では、フィールド「id」は自動インクリメントされる主キーであるため、プロシージャによって挿入されません。この手順では、最初にテーブル T1 と T2 にデータを挿入し、次にテーブル T1 から最大の「id」(最後に挿入された/自動インクリメントされた「id」) を、「insert ignore into」によって自動生成された変数「max_id」で読み取ります。 T1....." このプロシージャのクエリ。
マルチスレッドを使用しているJavaコードを介してこの手順を呼び出しています。
私の問題は、「set @max_id:=(select max(id) from T1);」というステートメントです。このセッション/スレッドの「insert ignore into T1 .....」クエリによって生成された最後の自動インクリメント値を読み取る代わりに、間違った値を読み取ることがあります (別の並列スレッドがそのデータをテーブルに挿入している可能性があるため)現在のスレッドが T1 から "max_id" を読み取る前の T1 であるため、"max_id" は別のスレッドによってインクリメントされた値を取得しています)。
では、この問題を解決するにはどうすればよいでしょうか。分離レベルを変更することで解決できますか?
これらのテーブルは、INNODB ストレージ エンジンを使用しています。
「@@GLOBAL.tx_isolation」は「REPEATABLE-READ」です
「@@tx_isolation」は「REPEATABLE-READ」です
「@@autocommit」は「1」です
ありがとうございます。それでは、お元気で