2010-04-08 2 views
1

현재 프로젝트에서 제 3 자 데이터 제공 업체와 상호 작용하고 있습니다. 우리 테이블에 데이터를 삽입해야합니다. 이 삽입은 매 1 분마다, 매 5 분마다, 매 30 분마다 수행 할 수 있으며, 제공해야하는 새 데이터의 양에 따라 달라집니다. 분리 레벨 읽기 확약 사용. 우리는 2 분마다 webservice를 호출하여이 테이블에 새로운 데이터가 있는지 확인하는 애플리케이션 인 Windows 서비스를 제공합니다. 우리의 격리 수준은 반복해서 읽을 수 있습니다. 레코드를 검색하고이 행의 열을 업데이트합니다.문제를 일으키는 테이블 동시 사용

이제는이 제 3 자 제공 업체가 많은 데이터를 삽입해야하는 경우가 있는데, 5000 레코드라고합시다. 트랜잭션 당이 작업을 수행하지만 (트랜잭션 당 5rows) 연결을 종료하지는 않습니다. 그들은 하나의 트랜잭션을 수행 한 다음 모든 레코드가 삽입 될 때까지 다음 트랜잭션을 수행합니다. 이로 인해 프로세스에 문제가 발생하여 시간이 초과되었습니다.

오랜 시간 동안 계속되면 데이터베이스가 완전히 불안정합니다. 예를 들어, 아마 멈췄을지라도, 테이블은 어떻게 든 여전히 사용할 수 없게됩니다. 테이블에서 선택을하려고 할 때 여러 레코드가 생기지 만 특정 순간에는 더 이상 응답이 없습니다. 그것은 데이터를 검색하는 것을 말하지만 시간 초과 예외가 발생할 때까지는 아무 것도 나오지 않습니다.

유일한 해결책은 데이터베이스를 다시 시작한 다음 다른 레코드를 보는 것입니다.

어떻게 해결할 수 있습니까? 이 시나리오에서 이상적인 격리 수준 설정은 무엇입니까?

답변

1

아마도 타사 데이터 제공 업체가 쓸 수있는 스테이징 테이블을 만들 수 있습니다. 그런 다음 자신의 루틴을 작성하여 응용 프로그램에서 더 잘 작동하는 선택 방법을 사용하여 거기에서 실제 테이블로 데이터를 가져올 수 있습니다. 당신이

질문에

영업 이익의 의견에 따라

편집 이제 문제는 때때로이 타사 공급자의 5000 개 기록을 가정 해 봅시다, 데이터의 많이 삽입 할 필요가 있다는 것입니다 . 트랜잭션 당이 작업을 수행하지만 (트랜잭션 당 5 개), 연결을 닫지 않습니다. 그들은 트랜잭션을 수행 한 다음 모든 레코드가 삽입 될 때까지 다음 트랜잭션을 수행합니다. 이로 인해 문제가 발생하여 시간이 초과되었습니다.

이는 제 3 자 데이터 제공 업체가 데이터를 삽입하는 방식으로 문제를 확인했음을 나타내며 변경하는 데 도움이되지 않는다는 것을 나타냅니다. 스테이징 테이블에 삽입하도록 제안하면 제 3 자 데이터 제공자에 의한 잠금 및/또는 차단을 위해 애플리케이션이 해제됩니다. 그런 다음 분리 수준, 한 번에 여러 행 수, 시간 또는 특정 시간 등을 사용하여 응용 프로그램에 데이터를 자유롭게 포함시킬 수 있습니다.

그러나 새 행을 테이블이 응용 프로그램을 잠글 수 있습니다. 잠금/블로킹 인 경우 응용 프로그램이 어쨌든 삽입되는 동안 새 행을 읽는 이유는 무엇입니까? 테이블의 중간에 행이있는 클러스터 된 인덱스를 사용하여 삽입 하시겠습니까?귀하의 응용 프로그램이 트랜잭션에서 테이블 스캔 선택을하고 있습니까? 뭔가 다른 일이있을거야.

하면 시스템이 죽을 이것을 시도하기 시작할 때, 그것은 블록의 원인이 무엇을 보여줍니다 :

;with Blockers AS 
(SELECT 
    r.session_id AS spid 
     ,r.cpu_time,r.reads,r.writes,r.logical_reads 
     ,r.blocking_session_id AS BlockingSPID 
     ,LEFT(OBJECT_NAME(st.objectid, st.dbid),50) AS ShortObjectName 
     ,LEFT(DB_NAME(r.database_id),50) AS DatabaseName 
     ,s.program_name 
     ,s.login_name 
     ,OBJECT_NAME(st.objectid, st.dbid) AS ObjectName 
     ,SUBSTRING(st.text, (r.statement_start_offset/2)+1,((CASE r.statement_end_offset 
                    WHEN -1 THEN DATALENGTH(st.text) 
                    ELSE r.statement_end_offset 
                   END - r.statement_start_offset 
                  )/2 
                  ) + 1 
        ) AS SQLText 
    FROM sys.dm_exec_requests       r 
     JOIN sys.dm_exec_sessions      s ON r.session_id = s.session_id 
     CROSS APPLY sys.dm_exec_sql_text (sql_handle) st 
    --WHERE r.session_id > 50 
) 
SELECT Blockers.* FROM Blockers 
+0

을 조사 할 필요가이 수준 와 함께 일하지 않았하지만 그때를 하나의 테이블에서 다른 테이블로 데이터를 전송하는 것입니까? – Sven

+0

솔직히 말하면, 나는 정말로 문제가 어디에 있는지도 모른다. 대용량의 데이터가 삽입되는 경우가 있으며 2 분마다 실행되는 프로세스가 있습니다. 문제는 그들이 테이블을 비우지 않고, 자물쇠가 보관되며, 잘 모르겠다는 생각입니다. 나는 당신의 생각에서 영감을 얻었으며 다음을 생각하고있었습니다. 만약 내가 그들에게 그들 자신의 테이블을 주면 내가 직접 테이블을 만들면 어떨까요? 테이블 위에는 데이터를 복사 할 데이터베이스 트리거를 넣을 것입니다. 데이터베이스 트리거 삽입으로 두 번째 테이블에 대한 액세스가 차단됩니까? 트리거가 사용하는 격리 수준은 무엇입니까? 내일이 스크립트를 사용하겠습니다! – Sven

+0

트리거를 사용하면 변경 사항이 표시되지 않습니다. 트리거는 타사 데이터 공급자가 사용하는 트랜잭션 내에서 실행되며 동일한 잠금/차단 문제를 일으킬 수 있습니다. 스테이징 테이블을 작성하는 경우 다른 실행 범위에 있고 완전히 제어 할 수 있도록 프로세스를 시작하도록 작업을 스케줄해야합니다. –

1

Snapshot isolation으로 생각하십니까? 아키텍처 측면에서 볼 때 타사의 통합 메커니즘을 만들고 삽입을 직접 처리하면 Message Queue를 통해 업데이트를 보낼 수 있습니다.

+0

이 같은 문제가 발생하지 않습니다 – Sven

관련 문제