0

同時リクエストの場合、重複した挿入で次の問題が発生しています。

私は2つのテーブルを持っています:

create table tbl (
  val varchar2(1000)
);

create table tbl2 (
  val varchar2(1000)
);

テーブルが空tbl2の場合にのみ、テーブルに値を挿入する必要があります。tblしたがって、私のJavaコードでは、分離レベル= READ COMMITEDのトランザクションで行います:

//start transaction
int result = jdbcTemplate.queryForInt("select count(*) from tbl");
if (result == 0) {
  int update = jdbcTemplate.update("insert into tbl2(val) values(?)", "di" + UUID.randomUUID().toString());
}
//end transaction

ここでの問題は、誰かがif (result == 0)と私の更新ステートメントの間に実際にデータを挿入できることです。そのため、エントリが重複します。

私の例は単純化しすぎていますが、実際のケースはもっと複雑ですが、基本的な考え方は同じです。挿入する前に、Javacode 内からいくつかの選択を行う必要があります。

では、このような状況を回避するにはどうすればよいでしょうか (私は db 側のソリューションと Java 側のソリューションに興味があります)。

PS データベースは Oracle です。

4

2 に答える 2

2

このような状況を処理する最善の方法は、データベース レベルであると思います。次のようなクエリを使用できます。

insert into tbl2 values(xx) where not exists (select 1 from tbl1)

したがって、クエリは次のようになります

int update = jdbcTemplate.update("insert into tbl2(val) values(?) where not exists (select 1 from tbl1)", "di" + UUID.randomUUID().toString());
于 2012-07-13T23:26:10.763 に答える
1

なぜ自分がしていることをしたいのかよくわかりませんが、最初にテーブルをロックできます。

LOCK TABLE tbl IN SHARE MODE;

コミットすることを忘れないでください。ロックを解除します。

于 2012-07-13T22:52:09.867 に答える