2009-08-25 2 views
1

저는 수백 개의 사업 단위에서 야간 보고서를 받아야하는 서버를 개발 중입니다. 보고서는 현재 암호화 된 CSV 파일입니다. 총 보고서 수는 나중에 사용하기 위해 데이터베이스에 저장되는 매일 500 000 - 1 000 000 레코드에 이릅니다.동시 배치 처리에서 JDBC 명령문 캐시를 생략하는 방법은 무엇입니까?

각 전송마다 PreparedStatements 세트를 생성했습니다. 이 명령.은 실행 W 확약 전에 50 개의 레코드를 일괄 처리하는 데 사용됩니다. 각 레코드로 인해 최대 20 개의 데이터베이스 삽입이 발생할 수 있습니다. 전송이 대기열에 있고 하나씩 처리되면 모두 잘됩니다.

나는이 작업을 동시에 시도 했으므로 다른 스레드가 PreparedStatements의 인스턴스와 똑같은 인스턴스를 가지고 있음을 발견했습니다. 이

  1. 다중 스레드가 스레드의 데이터베이스는 그것의 충족하지 않은 때 불렀다 그래서
  2. 커밋 할 시간이었다 결정했을 때
  3. 일괄 처리가 실행되는 것과 같은 배치에 문을 추가 한 다음 문제의 원인 스레드의 일부와 같은 제약이 질문은 문

의 일부를 사용하는 시간이 없었했다 : 준비된 문을 강제하는 방법 대신 명령문 캐시에서 기존 재사용의 이인가를 만들 수있다?

하지

  • 하여 데이터베이스에서
  • 떨어 제약을 풀링 문/연결되지 않은 일괄 처리에 대한 별도의 데이터 소스를 만드는 것보다 상황을 처리 할 수있는 더 좋은 방법이 있다면;

    가 보자 스레드 T1과 T2 할 문제를 명확히하기 위해 시도 : 순서는


편집 순차적 처리를 강제로 더 이상

  • 문제가되지 것 삽입합니다. 준비된 문장 S1과 S2를 보겠습니다. 배치 B1과 B2가 있다고합시다.

    S1을 사용할 때마다 B1에 추가됩니다. S2를 사용할 때마다 B2에 추가됩니다. 커밋 할 때 S1은 외래 키 제약 조건 당 S2보다 먼저 커밋되어야합니다.

    • T1이 T2는 전송을 처리 멋지게
    • 전송들을 처리 할 때

      문제가 발생 순수

    • T1 배치 B1 함유 S1A에 S1A 추가 명령문 S1을 사용
    • T1 배치 B2에 S2A 추가 명령문 S2를 사용 s2a 포함
    • T1이 커밋 할 시간이라고 결정했습니다.
    • T1 커밋 B1 배치 닝 S1A
    • T2는
    • T2는 S2A 함유 배치 B2에 S2B 추가 S2를 사용 S2B
    • T1이 '아니오'라고
    • 데이터베이스 S2B 일괄 B1의 containting의 S2A 커밋 배치 B1 함유 S1B로 S1B 추가 S1을 사용 외부 키에서 금지 된 s1b 전에 s2b가 확약됩니다.

    이것은 수동 동기화와 회답을 통해 피할 수 있지만 각 스레드의 로컬 논리를 적용하는 대신 각 배치의 크기를 따로 따로 추적해야합니다.

  • +0

    필요한 작업을 수행하려면 공급 업체별 방법을 사용해야합니다. 어떤 RDBMS를 사용하고 있습니까? – Juris

    +0

    아우. 그건 내가 듣고 싶었던 것이 아니다. 현재 테스트 시스템은 Apache Derby에서 실행됩니다. 프로덕션 데이터베이스는 Oracle 10g 또는 R이 될 것입니다. –

    +0

    두 가지 대답 모두 내 문제를 생각하는 데 도움이 될 것입니다. 테스트 할 때 내가 선택한 솔루션을 제공 할 것입니다. –

    답변

    0

    나의 현재 솔루션은 걱정 중지하고 공유 사랑의 시작입니다 배치. 잠금이 현재의 thread에게 수여 될 때 나는 N의 레코드 집합을 구문 분석 배치로 N 레코드의 집합을 intermidiate 형식

  • 에 저장 지속 두 단계

    1. 로 처리 알고리즘을 분할했다

    이렇게하면 동시 및 일괄 처리 순차 분석이 가능합니다. 스레드 간의 대기 시간을 최소화하기 위해 달콤한 지점을 찾아야 할 것입니다.

    스위트 스폿에 대한 탐구는 일종의 2 단계 잠금 체계를 구현할 수 있습니다. 즉, 각 스레드가 원하는대로 수행하고 커밋 할 때 모든 스레드가 실제 일괄 처리 전에 현재 레코드를 완료했는지 확인하십시오.

    후자의 솔루션에서는 문제가 있는지 테스트하지는 않았지만 각 PreparedStatement에 대한 매개 변수 설정을 동기화해야 할 수도 있습니다. 그것해야합니다.

  • 1

    단일 연결 인스턴스에서 여러 개의 문을 사용하려고합니까? IMO, 설명하는 동작에 대해 연결 풀을 사용하는 것이 좋습니다. 다른 방법은 수동으로 동기화하는 것입니다.

    +0

    답변 해 주셔서 감사합니다. 각 스레드마다 하나의 연결이 있습니다. 각 연결에는 여러 개의 명령문이 있으며, 각각의 개별 SQL 문에 대해 하나의 PreparedStatement 인스턴스가 있습니다. 각 문에는 일괄 처리가 들어 있습니다. 문제는 문 캐싱 때문에 각 스레드가 일괄 처리에 문제를 일으키는 고유 한 문 집합을 가지고 있지 않다는 것입니다. 연결 풀 및 명령문 캐시는 연결 및 명령 준비 이벤트가 거의 없기 때문에 여기서는 도움이되지 않습니다. –

    +0

    문제를 이해하려고 아직도 노력하고 있습니다 - 명령문을 실행하는 순서가 문제입니까? – Everyone

    +0

    시나리오의 명확한 설명을 위해 (잘하면) 질문을 편집했습니다. 실행 명령으로 충돌이 발생합니다. 반면에 공유 된 진술 및 배치는 지역 국가를 신뢰하는 것을 불가능하게 만듭니다. 이것은 내 의견대로, 시나리오에서 실제 작업 스레드와 별도로 배치 관리를 피할 수있는/비 유리한 동시성을 발생시킵니다. –

    1

    이 솔루션은 공급 업체에 따라 다릅니다.

    코드가 서블릿에서 실행되는 경우 웹 응용 프로그램에서 데이터 소스를 구성하여 문제를 해결할 수 있습니다. Tomcat에서 Oracle 드라이버를 사용해 보았지만 다른 응용 프로그램 서버에서도 연결 풀링을 구성하는 방법이 비슷합니다.

    코드가 독립형이면 공급 업체별 API를 사용해야합니다. 프로덕션 데이터베이스로 오라클을 대상으로 할 때, 여기에 오라클 JDBC 드라이버에 대한 간단한 예입니다 : 오라클 10.2 JDBC dev guide 자세한 정보에 대한

    import oracle.jdbc.OracleConnection; 
    
    ... 
    
    public static void disableStatementCaching(java.sql.Connection conn) 
         throws SQLException { 
        ((OracleConnection)conn).setImplicitCachingEnabled(false); 
    } 
    
    ... 
    

    +0

    답장을 보내 주셔서 감사합니다. 나는 그것들을 사용하는 것에 대해 회의적 일지라도 벤더에 특정한 API를 확실히 볼 것이다. 응용 프로그램이 서블릿으로 실행되지 않습니다. EJB3 @WebService -annotation에 정의 된대로 웹 서비스로 게시됩니다. 그러나 응용 프로그램 서버 정의 데이터 소스를 사용하고 구성하는 것은 전적으로 가능합니다. 미래의 개발자가 성명 캐싱을 가능하게하여 성능을 최적화하기로 결정할 상황에 이르게하는 적절한 문서가 필요할뿐입니다. –

    관련 문제