2013-08-19 2 views
0

쓰기 다중 스레드, 나는 다음과 같은 활동 파일을 생성하는 데이터 생성을위한 장소를
교착 상태 발생하는 동일한 테이블 내 응용 프로그램에서

1.Run 스크립트 A를 가지고 코드 조각이있을 때
2.Parse 파일에서 파일 및 데이터를 읽습니다.
3. 3 개의 다른 테이블에 데이터를 저장하고 그 날짜의 기존 행을 부실로 표시하기 전에 저장하십시오.
4.Run 스크립트 B
5. parse file by B
6. 2 개의 다른 테이블에 데이터를 저장하고 그 날짜의 기존 행을 오래된 것으로 표시하기 전에 저장하십시오.
7. 활동 감사를 테이블에 기록하고 메일을 보내십시오.

이제이 7 단계가 10-12 개의 다른 엔티티에 대해 병렬로 수행됩니다. 플랫폼은 JAVA, Spring, Ibatis이며 새 스레드 ISOLATION LEVEL이 READ COMMITTED 인 트랜잭션에서 각 프로세스에 대해 전체 프로세스를 수행하고 있습니다. thread는 corepoolsize = maxPoolsize가 10 인 ThreadPoolExecutor에 의해 관리됩니다. 테이블의 크기는 약 30K이고 각 테이블에 대해 작성되거나 업데이트되는 데이터의 양은 약 100 행입니다. 사용중인 데이터베이스는 SQL 서버입니다.

문제는 @Transactional 표기법이 예상대로 작동하지 않지만 각 스레드의 트랜잭션에서 7 단계가 완료되면 프로세스가 멈추고 단순히 진행되지 않습니다. 일시 중단 된 상태의 쿼리를 조사 할 때 3-4 개의 쿼리가 3 단계를 수행하려고 시도하고 '해당 날짜의 기존 항목을 부실 항목으로 업데이트'에서 멈추는 것으로 나타났습니다. 이렇게하면 잠금이 확대되고 5-10 분 후에 전체 데이터베이스가 잠기므로 다른 작업으로 인해 교착 상태가 발생하는 것을 방지 할 수 있습니다.
실제 교착 상태가 발생하지 않는다는 점에 유의하십시오. 작업은 단순히 진행되지 않습니다.
솔루션 시도 : SQL 서버가 특정 행을 식별하고 잠글 수 있도록 테이블에 클러스터되지 않은 색인 생성.
문제에 대한 해결책이나 가능한 원인을 제안하십시오. 일부 조사 및 분석 한 후

편집, 나는 해결책을 알아 낸. 나는 모든 데이터가 생성 된 후에 쓰레드 끝에서 3,6,7 단계를 움직였다. 그래서이 단계는 이제 별도의 메소드에서 수행되고 @Transaction 표기법은 트랜잭션에서 전체 스레드 조작을 수행하는 대신 메소드에만 적용됩니다. 이 메소드는 '동기화 된'메소드로 만들어 졌으므로 10 개의 스레드가 활성화되어 있어도 언제든지 하나의 스레드 만 DB에 쓸 수 있습니다. 이렇게하면 여러 스레드가 쓰려고하는 걱정을 없앨 수 있습니다 DB를 동시에.
이 접근법을 테스트했지만 앞에서 본 문제 중 어느 것도 현재 존재하지 않지만 단지 @ Transactional으로 주석을 달고 으로 동기화하는 것이 바람직하지 않은 영향을 미친다는 것을 알고 싶습니다. 또한 동기화 된 방법으로 DB에 작성하는 것이 좋습니다.

이전 문제의 실제 원인에 관심이있는 사람들에게는 적절한 이유가 될 수도 있고 그렇지 않을 수도 있습니다. 스레드가 멈추는 한 가지 이유는 스레드 풀 실행 프로그램의 최대 크기가 10 스레드이고 Apache DBCP 풀의 최대 크기가 8DB 연결 이었기 때문입니다. 따라서 첫 번째 스레드가 트랜잭션에 들어가고 5 분 (minEvicatableTime) 동안 유휴 상태를 유지하면이 스레드는 축출되었으며 다른 스레드에 연결되었습니다.이제 DB 연결이 없으므로 첫 번째 스레드는 완료 할 수 없지만 테이블을 첫 번째 스레드가 잠그면 연결을 확보 한 다른 스레드는 데이터를 쓸 수 없습니다.

+1

[행 수준 잠금 필요] (http://stackoverflow.com/questions/10648448/i-need-row-level-locking) 또는 [행 수준 강제로 가능합니까? SQL Server에서 잠금?] (http://stackoverflow.com/questions/3114826/is-it-possible-to-force-row-level-locking-in-sql-server)? –

+0

문제가 잠금 에스컬레이션 때문인지 또는 커밋되지 않는 트랜잭션으로 인한 것인지 정확하게 알 수 없습니다. 이상 적으로 업데이트되는 행 수는 5000 개 미만인 잠금 에스컬레이션이 발생하지 않아야합니다. – user1314361

+0

아마 위의 액티비티가 3, 6, 7에 대해 어떻게 구현되었는지 확인하기 위해 코드를 게시해야합니다. (있을 경우) 트랜잭션 관련 구성을 추가하십시오. –

답변

0

어떤 종류의 잠금 구성표가 테이블에 적용됩니까?

우리는 사용자가 테이블에서 엑셀 시트를 일괄 업로드 할 수있는 유사한 응용 프로그램을 보유하고 있습니다. 이러한 종류의 교착 상태를 막기 위해 사용자가 작업을 완료 할 때까지 해당 작업을 예약합니다. 다른 사용자는이 기간 동안 동일한 작업을 사용할 수 없습니다.

+0

1 단계에서 발생하는 데이터 생성 부분이 일부 엔티티의 경우 1 시간 이상 걸리기 때문에이 방법을 사용할 수 없습니다. 따라서 프로세스를 병렬 처리하고자합니다. – user1314361