0

dep_id と emp_id の主キーを持つテーブルへの Insert ステートメントがあります。私の Java プログラムは、新しいレコードの新しい emp_id を生成して挿入します。たとえば、dep_id = 100 および emp_id = 25 の場合、dep_id = 100 および emp_id = 26 のレコードを挿入できませんが、dep_id = 100 および emp_id = 27 の場合は挿入できます。その組み合わせ (dep_id = 100 および emp_id = 26) の何かが存在する場合、ステートメントを選択します。そのようなものは何もありません。私はまだ dep_id = 100 および emp_id = 26 から DELETE を実行し、念のためコミットしてから挿入しようとしましたが、それでも機能しません。何が間違っている可能性がありますか? コードは次のとおりです。変更された DDL および Insert ステートメント (Eclipse コンソールから取得)

                                                                                    CREATE  TABLE "TestDB"."table1" 
 (  "dep_id" NUMBER(20,0), 
"emp_id" NUMBER(20,0), 
"STATUS" VARCHAR2(10 BYTE), 
"PRO_LEVEL" VARCHAR2(14 BYTE), 
"new_sql_stmt" VARCHAR2(4000 BYTE), 
"DEL_TEM" VARCHAR2(500 BYTE), 
"tab_name" VARCHAR2(4000 BYTE), 
"COL_NAME" VARCHAR2(4000 BYTE), 
"QUERY_TYPE" VARCHAR2(4000 BYTE), 
"NAME" VARCHAR2(4000 BYTE), 
"DT_MODIFIED" DATE DEFAULT SYSDATE

)

  CREATE UNIQUE INDEX "TestDB"."table1_PK" ON "TestDB"."table1" ("dep_id", "emp_id") 


     INSERT into table1            (dep_id,emp_id,status,new_sql_stmt,tab_name,col_name,query_type,NAME)values('100','26','Unlock','INSERT into testTab(id_some,nm_some,id_some_origin,flag,some_code,author,order) values  (''S11111111'',''trialSome00'','''',''y'','''',''100'',0)','testTab','nm_some','INSERT','trialSome00')

Insert ステートメント自体には、値として別の Insert ステートメントがあることに注意してください。この Insert ステートメント (メインのステートメント) は、アプリの他の多くの場所で使用されます。また、私が使用する dep_id 100 はテスト用の dep_id です。私以外誰も使っていません。

4

1 に答える 1

1

Oracle シーケンスを作成します。

CREATE SEQUENCE emp_id_seq MINVALUE 1 START WITH 1 INCREMENT BY 1; 

これで、コード内からそのシーケンスで「nextval」メソッドを呼び出すことができます (これは JDBC またはほとんどすべての ORM で実行できます)。シーケンスを挿入し、挿入を行うたびにテーブルに挿入します(オラクルのIIRCでは、トリガーで「BEFORE INSERT」演算子を使用します)。

例えば

create or replace trigger mytable_emp_id_trigger
before insert on mytable
for each row
begin
    select emp_id_seq.nextval into :emp.id from dual;
end;
/

この方法はスレッドセーフであり、このような競合が発生することはありません。

Javaコード内でそれを行うことを主張する場合(DBAが別のシーケンスを作成することを許可しないと言いますが、そうしないと驚くでしょう)、そのメソッドをスレッドセーフにする必要があります。 . 次の値を提供する同期メソッドを使用してシングルトン (シングルトン EJB を作成できます) を作成するのがおそらく最善です。現在発生しているような問題を回避するために、他のクラスや ejb ではなく、そのシングルトン クラスから ID を取得します (現在の問題がこれによるものであるかどうかにかかわらず、現在発生しているのは、複数のスレッドが非同期で競合する典型的なものです)マルチスレッド環境でのメソッド)。

それまでの間、何が起こっているのかを本当に理解したい場合は、デバッガーを使用して変数を監視し、既存のコードが何を生成しているかを確認してください。デバッガーとウォッチはあなたの友達です。あなたの親友。

于 2012-07-11T18:16:11.840 に答える