2017-05-18 17 views
1

3 계층 앱이 있고 데이터가 클라이언트 측에 캐시되어 있으므로이 캐시를 동기화하기 위해 서버에서 데이터가 변경된시기를 알아야합니다.테이블 업데이트시 교착 상태 방지하기

그래서 테이블에 "lastmodification"필드를 추가하고 데이터가 변경되면이 필드를 업데이트합니다. 그러나 자식 행 (FK 사용)이 수정 될 경우를 대비하여 일부 '부모'마지막 수정 행을 업데이트해야합니다.
주 테이블에서 MAX (마지막 수정 날짜)를 가져오고 관련 테이블에서 MAX를 가져 오면이 여러 값의 MAX가 작동하지만 약간 느립니다. 는 말은 :

MAX(MAX(MAIN_TABLE), MAX(CHILD1_TABLE), MAX(CHILD2_TABLE)) 

그래서 내가 전환과는 TBL_METADATA 테이블에서 필드를 업데이트 할 수 있도록이 테이블에 트리거를 추가 :

CREATE TABLE [TABLE_METADATA](
    [TABLE_NAME] [nvarchar](250) NOT NULL, 
    [TABLE_LAST_MODIFICATION] [datetime] NOT NULL 

지금 관련 테이블 마지막으로 '주'테이블을 업데이트 할 수 있습니다 수정 시간은 메타 데이터 테이블의 마지막 수정 만 업데이트하면됩니다. 마지막 수정 가져 오기가 이제는 빠릅니다.

하지만 ... 이제이 테이블을 업데이트하는 것과 관련하여 임의의 교착 상태가 발생했습니다.

이것은 다른 단계에서 TABLE_METADATA를 수정 한 다음 서로 잠그는 2 개의 트랜잭션 때문입니다.

내 질문 :이 마지막 수정 사항을 행을 잠그지 않고 유지하는 방법이 있습니까? 내 경우에는 정말 경우 걱정하지 않는다 :

  • lastmodification는 트랜잭션이 롤백 경우에도 업데이트를 유지
  • '더러운'lastmodification (업데이트 아직 확정되지 않음) 새 값으로 덮어 입니다

실제로 이러한 업데이트가 트랜잭션에 필요하지 않지만 트리거에 의해 실행되므로 현재 트랜잭션에 자동으로 적용됩니다.

도움 주셔서 감사합니다.

+0

here. 당신은 같은 것을 사용하여 시도가 테이블 힌트에 대한

update mt with (rowlock) set SomeColumn = Something from MyTable mt where mt.Id in (select Id from MyTable mt2 where Column = Condition) 

더 많은 문서를 찾을 수 NOLOCK 힌트? 그게 어떤 잠금 장치 광고를하지 않고 업데이 트됩니다 그 때문에 교착 상태가 발생해서는 안됩니다 – Antonio

+0

내가 선택에 대한 NOLOCK 힌트를 알고 있지만 그것을 업데이트 할 때 사용할 수 있었는지 몰랐어? 나는 이것에 대해 확인해 보겠습니다. – Fabske

+0

nevermind, SELECT 만 잊었습니다 ... 시도해보십시오. "INSERT, UPDATE의 대상 테이블에는 NOLOCK 및 READUNCOMMITTED 잠금 힌트가 허용되지 않습니다. , DELETE 또는 MERGE 문을. " – Antonio

답변

1

내가 아는 한 U- 락을 방지 할 수 없습니다. 그러나 with (rowlock)을 사용하여 잠금 수를 최소로 줄여보십시오. 이렇게하면 페이지 또는 테이블 잠금을 사용하지 않고 행이 업데이트 될 때마다 행을 잠그도록 쿼리 최적화 프로그램에 지시합니다.

with (nolock)은 업데이트중인 테이블에 조인 된 테이블에서도 사용할 수 있습니다. 이에 대한 대안은 set transaction isolation level read uncommitted을 사용하는 것입니다. 잠재적으로 손상된 데이터를 만들 수 있으므로이 방법을 사용할 때는주의하십시오. 예를 들어

:

update mt with (rowlock) 
    set SomeColumn = Something 
    from MyTable mt 
     inner join AnotherTable at with (nolock) 
     on mt.mtId = at.atId 

또한 추가로 발생하는 교착 상태의 가능성을 줄이기 위해 with (rowlock) 자주 읽고 같은 테이블 쓰기 다른 데이터베이스 객체에 with (nolock)/set transaction isolation level read uncommitted를 추가 할 수 있습니다.

교착 상태가 계속 발생하는 경우는 다음과 같이 가입 자체가 목표 테이블에 잠금 읽을 줄일 수

+1

이것은 매우 흥미로운 대답입니다. 업데이트가 커밋되지 않은 읽기와 결합 될 경우 업데이트가 더 빠르게 진행될 것이라는 제안을 본 적이 없습니다 (많은 공유 및 배타적 잠금 포함). 업데이트를 수행 할 때 '올바른'행을 업데이트하고 있는지 확인하고 싶습니다. nolock과 결합하면 (커밋되지 않은 읽기이므로 커밋되지 않는 변경 내용을 사용하고있을 수 있음) 일부 매우 흥미로운 데이터가 손상 될 수 있습니다. –

+0

당신은 좋은 지적을 가지고 있습니다. OP가 "더러운"업데이트/읽기에 대해별로 신경 쓰지 않는다고 말하면서 언급하지 않았습니다. 이것에 대한 작은 섹션을 추가하겠습니다. –

+1

사용자가 걱정하지 않는다고 말하면서 나쁜 행동을해서는 안됩니다. 커밋되지 않은 읽기가 적절한 경우는 거의 없습니다. –