2008-09-17 4 views
10

파티션 된 postgresql 테이블에서 최대 절전 모드를 통해 배치 삽입을위한 솔루션이 있습니까? 현재 나는이 문제가 해결 내가이 링크 http://lists.jboss.org/pipermail/hibernate-dev/2007-October/002771.html를 발견하지만 난 어디에서나 웹에서 찾을 수없는이 같은 오류 ...파티션 된 postgresql을 가진 hibernate 삽입 배치

ERROR org.hibernate.jdbc.AbstractBatcher - Exception executing batch: 
org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1 
    at org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:61) 
    at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:46) 
    at org.hibernate.jdbc.BatchingBatcher.checkRowCounts(BatchingBatcher.java:68).... 

입니다 얻고있다거나 주위

+0

다른 모든 솔루션은 최대 절전 모드 3.5? –

답변

4

을 얻을 수있는 방법 hibernate.jdbc.factory_class 속성을 설정하여 커스텀 Batcher를 사용해 볼 수도있다. 최대 절전 모드로 배치 작업의 업데이트 횟수를 확인하지 않으면 문제를 해결할 수 있습니다. 사용자 정의 Batcher를 클래스 BatchingBatcher로 확장 한 다음 doExecuteBatch (...) 메소드를 재정 의하여 구현할 수 있습니다.

@Override 
    protected void doExecuteBatch(PreparedStatement ps) throws SQLException, HibernateException { 
     if (batchSize == 0) { 
      log.debug("no batched statements to execute"); 
     } 
     else { 
      if (log.isDebugEnabled()) { 
       log.debug("Executing batch size: " + batchSize); 
      } 

      try { 
//    checkRowCounts(ps.executeBatch(), ps); 
       ps.executeBatch(); 
      } 
      catch (RuntimeException re) { 
       log.error("Exception executing batch: ", re); 
       throw re; 
      } 
      finally { 
       batchSize = 0; 
      } 

     } 

    } 

새 메서드는 준비된 문을 실행 한 결과를 확인하지 않습니다. 이 변경 작업은 예상치 못한 방식으로 최대 절전 모드에 영향을 미칠 수 있습니다 (또는 아닐 수도 있음).

2

thnx!

property name="hibernate.jdbc.factory_class" value="path.to.my.batcher.factory.implementation" 

:이 같은 , BatcherFactory 클래스를 구현하고는 persistence.xml 파일을 int로 넣어했다) .... 네가 한 가지 ... : 그것은 트릭, 지금까지 최대 poped 아무런 문제를했다 그 공장에서 난 3.2.6 GA

에게

PS 최대 절전 모드 코어 위의 코드 내 디스펜서 구현

덕분에 그들은 말할 다시 한번

+0

일괄 처리 횟수를 무시하면 문제가 해결 되는가 아니면 오류 만 무시합니까? 동일한 오류가 발생했는데 이유가 무엇인지, 아니면 건너 뛰도록 배터를 재정의하려고하면 어떤 의미인지 알 수 없습니다. – Dougnukem

+1

이것은 Hibernate 3.2.6 GA에서 어떻게 작동 하는가? BatchingBatcher 구현체는 batchSize를 private 필드로 가지고있다. 그래서 그것을 확장하면 접근 할 필요가 없다. – Dougnukem

+1

그것은 문제를 무시하지만 모든 값은 DB에 있으므로 나에게 속임수가됩니다 ... 나는 AbstractBatcher 클래스를 확장했습니다. – tropikalista

2

라고했습니다 분할 된 테이블이나 @SQLInsert 주석에서 두 개의 트리거를 사용하십시오 : http://www.redhat.com/f/pdf/jbw/jmlodgenski_940_scaling_hibernate.pdf 21-26 페이지 (@SQLInsert는 String 메소드를 지정합니다). 하지만, 당신은 다음 오른쪽 숫자를 반환 할 수 있습니다, 삽입 대신 트리거 규칙을 사용할 수 있는지 https://gist.github.com/copiousfreetime/59067

+0

@SQLInsert 메서드가 작동했습니다. –

1

가 나타납니다 : 여기

마스터에서 여분의 행을 삭제하는 트리거 후와 예입니다 WHERE 문이없는 단일 RULE.

ref2

ref3

또 다른 옵션은 '랩'파티션 테이블, 당신은 성공적인 행 업데이트를 표시하기 위해 새 행을 반환하는 뷰를 만들 수 있습니다

ref1

없이 실수로 여분의 원치 않는 행을 마스터 테이블에 추가합니다.

create view tablename_view as select * from tablename; -- create trivial wrapping view 

CREATE OR REPLACE FUNCTION partitioned_insert_trigger() -- partitioned insert trigger 
RETURNS TRIGGER AS $$ 
BEGIN 
    IF (NEW.partition_key>= 5500000000 AND 
     NEW.partition_key < 6000000000) THEN 
     INSERT INTO tablename_55_59 VALUES (NEW.*); 
    ELSIF (NEW.partition_key >= 5000000000 AND 
      NEW.partition_key < 5500000000) THEN 
     INSERT INTO tablename_50_54 VALUES (NEW.*); 
    ELSIF (NEW.partition_key >= 500000000 AND 
      NEW.partition_key < 1000000000) THEN 
     INSERT INTO tablename_5_9 VALUES (NEW.*); 
    ELSIF (NEW.partition_key >= 0 AND 
      NEW.partition_key < 500000000) THEN 
     INSERT INTO tablename_0_4 VALUES (NEW.*); 
    ELSE 
     RAISE EXCEPTION 'partition key is out of range. Fix the trigger function'; 
    END IF; 
    RETURN NEW; -- RETURN NEW in this case, typically you'd return NULL from this trigger, but for views we return NEW 
END; 
$$ 
LANGUAGE plpgsql; 

CREATE TRIGGER insert_view_trigger 
    INSTEAD OF INSERT ON tablename_view 
    FOR EACH ROW EXECUTE PROCEDURE partitioned_insert_trigger(); -- create "INSTEAD OF" trigger 

심판 : http://www.postgresql.org/docs/9.2/static/trigger-definition.html

당신은 하나의 옵션은 또한뿐만 아니라, 삭제 및 업데이트 트리거 "대신"사소한 정의하는 뷰 래퍼 길을 갔다면, 당신은 단지의 이름을 사용할 수 있습니다 모든 거래에서 정상 테이블 대신보기 테이블을 사용하십시오.

보기를 사용하는 또 다른 옵션은 기본 테이블의 모든 삽입이 [해당 트리거를 사용하는]보기 (예 : partitioned_insert_trigger 및 tablename_view 및 insert_view_trigger가 위에 나열된대로 있다고 가정 할 때)로 이동하는 삽입 규칙을 만드는 것입니다)

create RULE use_right_inserter_tablename AS 
     ON INSERT TO tablename 
     DO INSTEAD insert into tablename_view VALUES (NEW.*); 

그런 다음 새로운 작업보기 래퍼 삽입을 사용합니다.

0

검색을 많이 한 후에도 최대 절전 모드로 문서를 삽입하는 동안 같은 문제가 발생했습니다. 업데이트 된 행이 반환되어야하므로 null 대신에 다음과 같이 문제를 해결할 트리거 프로 시저에서 새 것으로 변경하십시오.

돌아 가기