2012-07-11 8 views
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)이있는 경우 select 문을 사용하십시오. 그런 종류의 것은 없습니다. 나는 여전히 에서 dep_id = 100 및 emp_id = 26을 삭제하고 Commit 을 삽입하고 삽입하려고했으나 여전히 작동하지 않습니다. 무엇이 잘못 되었을까요? 코드입니다 follwing을 (이클립스 콘솔에서 획득) 수정 DDL 및 삽입 문ORA 000001 고유 한 제약 조건이 위반되었습니다.

                    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 문 (기본 문)은 응용 프로그램의 다른 많은 위치에서 사용됩니다. 또한, 내가 사용하는 dep_id는 테스트 dep_id입니다. 아무도 그것을 사용하지하지만 나.

+0

자바 코드가 동기화되어 있는지 확인하십시오. 여러 스레드에 의해 호출 될 수 있습니다. –

+0

스레드가없는 간단한 응용 프로그램 – Raghu

+1

설명하는 것은 의미가 없습니다. 이탈하는 부분 (즉, 다른 세션을 실행 중이고 잠재적으로 다른 응용 프로그램을 실행 중이고'dep_id = 100' 및'emp_id = 26 '을 사용하여 행을 삽입 및 커밋) 또는 설명이 잘못되었습니다. DDL을 게시하여 테이블을 만들고 문제를 복제하기 위해 컴퓨터에서 실행할 수있는 샘플 코드를 게시 할 수 있습니까? –

답변

1

오라클 시퀀스 만들기 : 이제

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

을 할 수 있습니다 중 하나를 코드 내에서 그 순서에 "NEXTVAL"방법을 (이 JDBC으로 수행하거나 거의 모든 ORM 모두없는 경우에 할 수있다)를 호출 , 또는 시퀀스에서 nextval을 자동으로 가져 와서 삽입 할 때 (oracle에서 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; 
/

이렇게하는 것은 스레드로부터 안전하므로이 같은 충돌이 발생하지 않아야합니다.

자바 코드 내에서 그렇게하고 싶다면 (DBA가 다른 시퀀스를 만들지는 못하지만 왜 그렇게하지 않으면 놀라지 않을 것인가?) 그 방법은 스레드 안전합니다. 다음 값을 제공하는 동기화 된 메서드로 싱글 톤 (싱글 톤 EJB를 만들 수 있음)을 만드는 것이 가장 좋습니다. 당신은 당신이 지금 가지고있는 것과 같은 이슈를 피하기 위해 다른 클래스 나 ejb가 아닌 싱글 톤 클래스로부터 ID를 얻습니다. 현재 문제가 발생했는지 여부에 관계없이 현재 발생하고있는 것은 여러 스레드가 비동기 적으로 충돌하는 전형적인 것입니다 다중 스레드 환경의 메소드).

그 동안 디버거를 사용하고 무슨 일이 일어나고 있는지 실제로 알고 싶다면 변수를 주시하여 기존 코드가 생성하는 것을 확인하십시오. 디버거와 시계는 친구입니다. 가장 친한 친구.

+0

BillR과 오늘 저를 도우려는 모든 분들께 감사드립니다. 문제의 원인을 아직 모른 채로 다음 값을 얻는 방법을 변경해야한다고 생각했습니다. 나는 이것으로 갈 것이다. – Raghu