programing

동면기의 오라클 시퀀스는 큰 갭을 만들어 낸다

goodcopy 2023. 3. 19. 20:18
반응형

동면기의 오라클 시퀀스는 큰 갭을 만들어 낸다

hibernate 3, oracle 10g을 사용하고 있습니다.표가 있습니다. 주제입니다.정의는 다음과 같습니다.

CREATE TABLE SUBJECT
    ( 
     SUBJECT_ID NUMBER (10), 
     FNAME VARCHAR2(30)  not null, 
     LNAME VARCHAR2(30)  not null, 
     EMAILADR VARCHAR2 (40),
     BIRTHDT  DATE       not null,
     constraint pk_sub primary key(subject_id) USING INDEX TABLESPACE data_index
    ) 
;

새 제목을 삽입할 때 sub_seq를 사용하여 제목 ID를 만듭니다. 정의는 여기에 있습니다.

create sequence sub_seq
       MINVALUE 1 
       MAXVALUE 999999999999999999999999999 
       START WITH 1
       INCREMENT BY 1 
       CACHE 100 
       NOCYCLE ;

Subject 클래스는 다음과 같습니다.

@Entity
@Table(name="ktbs.syn_subject")
public class Subject {

    @Id 
    @Column(name="subject_id")
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SUB_SEQ")
    @SequenceGenerator(name="SUB_SEQ", sequenceName = "SUB_SEQ")
    private long subjectId;
    private String fname;
    private String lname;
    private String emailadr;
    private Date birthdt;
}

서브젝트 테이블에는 4555개의 서브젝트가 엑셀로부터의 plsql 스크립트에 의해 로드되어 sub_sequence는 정상적으로 동작했습니다.subject ids 범위는 1 ~4555입니다

그러나 hibernate를 사용하여 어플리케이션에서 서브젝트를 추가하자 시퀀스 번호가 255050으로 뛰어올랐다.며칠이 지나면 휴지 상태에 의해 생성된 서브젝트 ID는 다음과 같습니다.

270079
270078
270077
270076
270075
270074
270073
270072
270071
270070
270069
270068
270067
270066
270065
270064
270063
270062
270061
270060
270059
270058
270057
270056
270055
270054
270053
270052
270051
270050
265057
265056
265055
265054
265053
265052
265051
265050
260059
260058
260057
260056
260055
260054
260053
260052
260051
260050
255067
255066
255065
255064
255063
255062
255061
255060
255059
255058
255057
255056
255055
255054
255053
255052
255051
255050
4555
4554
4553
.
.
.
.
1

4555~255051, 255067~260051, 265057~270051의 몇 가지 큰 차이가 있습니다.

이것은 낭비이며 바람직한 행동이 아닙니다.

왜 이런 일이 일어나는지 아는 사람이 있나요?

감사해요.

이 문제는 시퀀스 제너레이터가 실제로는 시퀀스 제너레이터가 아니라 디폴트 할당 사이즈가 50인 시퀀스 hilo 제너레이터라는 사실에 기인한다고 생각합니다.이 문서는 http://docs.jboss.org/hibernate/stable/annotations/reference/en/html_single/ #syslog-identifier 입니다.

즉, 시퀀스 값이 5000인 경우 다음에 생성되는 값은 5000 * 50 = 250000이 됩니다.시퀀스의 캐시 값을 방정식에 더하면 초기 갭이 클 수 있습니다.

시퀀스 값을 확인합니다.마지막으로 생성된 식별자보다 작아야 합니다.생성된 값이 기하급수적으로 증가하므로 시퀀스를 이 + 1로 다시 초기화하지 않도록 주의하십시오(이 문제는 발생했으며 오버플로로 인해 음의 정수 ID가 있음).

JB의 말에 동의해.하지만 여전히 Paul J에게 감사한다.

아래 주석 코드에 대한 자세한 내용은 다음과 같습니다.

@Entity
@Table(name="ktbs.syn_subject")
public class Subject {

  @Id 
  @Column(name="subject_id")
  @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SUB_SEQ")
  @javax.persistence.SequenceGenerator(name="SUB_SEQ", sequenceName = "SUB_SEQ")
  private long subjectId;
  private String fname;
  private String lname;
  private String emailadr;
  private Date birthdt;
}

「 」를 사용하고 javax.persistence.SequenceGenerator, hibernate 는 hilo 를 사용합니다.시퀀스에 큰 갭이 생길 수 있습니다.이 문제에 대처하는 투고가 있습니다.https://forum.hibernate.org/viewtopic.php?t=973682

이 문제를 해결하려면 두 가지 방법이 있습니다.

  1. 에서 SequenceGenerator를 합니다.allocationSize = 1, initialValue= 1
  2. javax.consence를 사용하는 대신 사용합니다.Sequence Generator 는 다음과 같이 org.hibernate.annotations 를 사용합니다.

    @javax.persistence.SequenceGenerator(
        name = "Question_id_sequence", 
        sequenceName = "S_QUESTION"
    )
    
    @org.hibernate.annotations.GenericGenerator(
        name="Question_id_sequence", 
        strategy = "sequence", 
        parameters = { 
            @Parameter(name="sequence", value="S_QUESTION") 
        }
    )
    

두 가지 방법을 모두 테스트해 봤는데, 잘 작동합니다.

「allocationSize=1」의 , allocationSize=1이면 .INCREMENT VALUE는 1이므로 많은 엔티티를 유지할 필요가 없습니다.그러나 수천 또는 수백만 개의 레코드를 유지하려면 위의 설정이 성능 병목현상이 될 수 있습니다.이는 저장마다 ID를 가져와야 하기 때문입니다.따라서 DB 읽기가 필요하기 때문입니다.

하려면 , 을 해 둘 .allocationSize이나 오백 같은 것에 INCREMENT VALUE500으로 , 한 것은 설정 DB 500을 합니다.hibernate.id.new_generator_mappings실장을 하려면 , 여기서 클래스에서 상태의 하고 있는 합니다.Java Config는 다음과 같습니다.

properties.setProperty("hibernate.id.new_generator_mappings", Boolean.toString(true));

하면 는 '하이버네이트'를 사용합니다.SequenceStyleGeneratorSequenceHiLoGenerator아이디 ★★★★★★★★★★★★★★★★★.SequenceStyleGenerator friendlyjpa는 oracle을 더 .시퀀스 스타일의 데이터베이스 구조를 기반으로 식별자 값을 생성합니다.실제 시퀀스를 사용하는 것부터 테이블을 사용하여 시퀀스를 모방하는 것까지 다양합니다.

같은 처지에 있는 경우 자세한 내용은 내 게시물을 참조하십시오.

vcfvct.wordpress.com/2016/04/23/jpa-sequencegenerator-with-allocationsize-1-performance-tuning/

또 다른 솔루션은 다음과 같습니다.

Type'을 사용합니다세대 유형'입니다.' Type'이아닌 'AUTOGeneration Type'은 'AUTO'입니다.SEQUENCE는 'SEQUENCE'의 전략으로 됩니다.@GeneratedValue하와와같같같같

@Id
@SequenceGenerator(name = "studentId", sequenceName = "student_Id")
@GeneratedValue(strategy = GenerationType.AUTO, generator="studentId")  
private int studentId;

다음 링크를 읽으면 시퀀스 작성 명령의 CASH 설정에 의해 문제가 발생했음을 알 수 있습니다.캐시 설정을 삭제하면 문제가 어느 정도 해결되지만 롤백 등의 가능성은 고려되지 않습니다.

링크: http://asktom.oracle.com/pls/apex/f?p=100:11:0:::P11_QUESTION_ID:369390500346406705

현재 시퀀스를 재동기화하는 유일한 방법은 시퀀스를 다시 만들고 현재 테이블의 이름을 변경한 후 테이블을 다시 만든 다음 이전 테이블의 레코드를 새 테이블에 다시 삽입하는 것입니다.

메모: 시퀀스의 캐시 값은 'x' 시퀀스 값이 한 번에 할당되는 큰 부하에 유용합니다.한 번에 한 개씩 삽입하는 트랜잭션 시스템을 사용하는 경우 캐싱은 유용하지 않습니다(또는 전혀 유용하지 않습니다).

메모: 다음은 시퀀스의 캐시 옵션에 대한 이해입니다.자세한 내용은 CREATE SEQUENCE 명령에 대한 Oracle 문서를 참조하십시오.그러나 위의 링크를 클릭하면 질문에 대한 합리적인 답변을 얻을 수 있습니다.

감사합니다. 폴

이를 위한 하나의 솔루션은 allocation Size를 사용하여 시퀀스 생성기를 다음과 같이 구성할 수 있습니다.

@SequenceGenerator(name = "gen_name", sequenceName = "seq_name", allocationSize= 1)

가장 성공적인 답변은 다음과 같습니다.

@Id
@SequenceGenerator (name = "id_sequence", sequenceName = "sq50")
@GeneratedValue(strategy = GenerationType.AUTO, generator = "id_sequence")
public int getId() {
return id;
}

유사한 문제가 있었습니다. 시퀀스 생성기와 시퀀스 힐로 생성기는 상당히 유사하지만 차이가 있습니다.휴지 상태 3에서는 hilo 제너레이터가 기본값 50을 곱합니다.따라서 DB 시퀀스를 늘릴 필요가 없습니다.한편, 하이버네이트의 최신 버전에서는 디폴트로 시퀀스 제너레이터가 사용됩니다.따라서 DB를 50만큼 늘려야 합니다.

https://access.redhat.com/documentation/en-US/JBoss_Enterprise_Application_Platform/6.3/html/Migration_Guide/Preserve_the_Existing_Behavior_of_the_Hibernate_Identity_Auto_Generated_Value1.html

이 문제는 여러 휴지 상태 버전(3과 5)이 있습니다.같은 설정이 정상적으로 동작했습니다(DB에서 1 증가).하지만 하이버네이션 5에서는 실패했습니다.따라서 다음과 같이 persistence.xml을 업데이트합니다.이것은 hilo 생성을 보장합니다.

        <property name="hibernate.id.new_generator_mappings" value="false" />

여기 말한 것처럼, 당신의 위치를 조정해 보세요.SequenceGenerator.allocationSize데이터베이스 시퀀스와 함께INCREMENT BY번호.

언급URL : https://stackoverflow.com/questions/5346147/hibernate-oracle-sequence-produces-large-gap

반응형