2017-05-03 4 views
2

Java 응용 프로그램에서는 SQL Server 문을 사용하여 일부 프로세스를 일시 중지합니다. 실행에서 물론 IN 절 변화(UPDLOCK, ROWLOCK)도 전체 테이블을 잠글 수 있습니다. 단 한 행만 선택했습니다.

SELECT * FROM MESSAGES WITH (UPDLOCK, ROWLOCK) 
WHERE MESSAGES.INTERNAL_ID IN ('6f53448f-1c47-4a58-8839-e126e81130f0'); 

UUID를 실행할 :

는 SQL 문입니다.

이 우리가 잠금에 사용하는 Java 코드 :

entityManager.createNativeQuery(sqlString).getResultList() 

위의 SQL 문을 하나의 행을 반환합니다. 불행히도 전체 테이블이 잠긴 것처럼 보입니다. 결과적으로 모든 프로세스가 잠기지 않거나 일부만 차단해야하는 결과가 발생합니다.

UPDLOCK을 지정하더라도 전체 테이블이 잠기는 이유는 무엇입니까?


추가 정보 :

  • MESSAGES.INTERNAL_ID이 널 (NULL) 입력하지 않은 NVARCHAR(255)이다. 그렇지 않으면 열에 제약 조건이 없습니다.
  • 격리 수준은 READ_COMMITTED입니다.
+0

'messages' 테이블 정의 (ID는 기본 키입니까?) 트랜잭션 격리 수준은 무엇입니까? –

+0

@MikhailLobanov 질문에 요청 된 정보를 추가했습니다. –

답변

1

MESSAGES.INTERNAL_ID이 키가 아니기 때문입니다. 행이 잠기면 읽을 수 없으며 값을 확인할 수 없습니다. 이 열에 기본 키를 만들어보십시오. 그것이 불가능하면

, 쿼리를 그 위에 INDEX를 작성하고 재 작성 :

SELECT MESSAGES.INTERNAL_ID FROM MESSAGES WITH (UPDLOCK, ROWLOCK) 
WHERE MESSAGES.INTERNAL_ID IN ('6f53448f-1c47-4a58-8839-e126e81130f0'); 

MSDN 말한다 :

잠금 행 수준 잠금을 획득 ROWLOCK, UPDLOCK, 및 XLOCK 힌트 할 수있다 실제 데이터 행 대신 색인 키에 대한 위치 잠금이 있습니다. 의 경우 테이블에 비 클러스터형 인덱스가 있고 잠금 힌트를 사용하는 SELECT 문 이 커버 인덱스에 의해 처리되는 경우 의 데이터 행보다는 커버 인덱스의 인덱스 키에 대해 잠금이 으로 획득됩니다. 기본 테이블.

+0

고마워요! 이제는 잠금을위한 기본 키를 사용하고 있습니다. –

+0

또 다른 질문 : 'SELECT MESSAGES.ID'는 중요한 부분입니까,'어디서 메시지입니까? ID'입니까? –

+0

기본 키를 만드는 경우 중요하지 않습니다. PK는 일반적으로 클러스터 된 인덱스입니다 (클러스터 된 인덱스는 항상 포함). 그러나 비 클러스터 인덱스를 만들려면 select list에주의해야합니다. –