programing

SQL Server에 데이터를 삽입하면 전체 테이블이 잠깁니까?

starjava 2023. 7. 11. 21:23
반응형

SQL Server에 데이터를 삽입하면 전체 테이블이 잠깁니까?

는 Entity Framework를 사용하고 있으며, 블로그 필드를 포함한 레코드를 데이터베이스에 삽입하고 있습니다.블롭 필드는 최대 5MB의 데이터일 수 있습니다.

이 테이블에 레코드를 삽입할 때 테이블 전체를 잠급니까?

따라서 테이블에서 데이터를 쿼리하는 경우 삽입이 완료될 때까지 차단됩니까? (이 문제를 해결할 수 있는 방법이 있다는 것을 알고 있지만 기본적으로 말하고 있습니다.)

교착 상태가 발생할 때까지 얼마나 걸릴까요?그 시간은 서버의 부하량에 따라 달라질까요? 예를 들어 부하가 많지 않은 경우 교착 상태가 발생하는 데 더 오래 걸릴까요?

특정 시간에 무엇이 잠겨 있는지 모니터링하고 확인할 수 있는 방법이 있습니까?

각 스레드가 단일 테이블에서 쿼리를 수행하는 경우 차단이 발생할 수 있는 경우가 있습니까?그렇다면 조인이 있고 여러 테이블에서 동작하는 쿼리가 있을 경우에만 교착 상태가 발생할 수 있는 것이 아닌가요?

이것은 제 코드의 대부분이 단지 선택된 문들의 묶음일 뿐, 장기간 실행되는 트랜잭션의 더미나 그런 것들이 아니라는 것을 고려한 것입니다.

세상에, 여기 질문이 많구나, 헤헤.다음은 몇 가지 답변입니다.

이 테이블에 레코드를 삽입할 때 테이블 전체를 잠급니까?

기본적으로 그렇지는 않지만 TABLOCK 힌트를 사용하거나 특정 종류의 대량 로드 작업을 수행하는 경우에는 그렇습니다.

따라서 테이블에서 데이터를 쿼리하는 경우 삽입이 완료될 때까지 데이터가 차단됩니까(이 문제를 해결할 수 있는 방법이 있다는 것을 알고 있지만 기본적으로 말하고 있습니다)?

이것은 좀 더 까다로워집니다.만약 누군가가 당신이 잠긴 테이블의 페이지에서 데이터를 선택하려고 한다면, 당신은 그들을 차단할 것입니다.선택한 문에 대한 NOLOCK 힌트를 사용하거나 Read Committed Snapshot Isolation(읽기 전용 스냅샷 분리)을 사용하여 이 문제를 해결할 수 있습니다.격리 레벨이 작동하는 방법에 대한 시작점은 Kendra Little의 격리 레벨 포스터를 확인하십시오.

교착 상태가 발생할 때까지 얼마나 걸릴까요?그 시간은 서버의 부하량에 따라 달라질 수 있습니까? 예를 들어 부하가 많지 않으면 교착 상태가 발생하는 데 더 오랜 시간이 걸릴 수 있습니까?

교착 상태는 시간에 기반한 것이 아니라 의존성에 기반한 것입니다.다음과 같은 상황이 발생했다고 가정합니다.

  • 쿼리 A는 여러 개의 잠금을 보유하고 있으며, 쿼리를 끝내기 위해서는 쿼리 B에 의해 잠기는 것이 필요합니다.
  • 쿼리 B는 또한 많은 잠금을 보유하고 있으며, 쿼리를 끝내기 위해서는 쿼리 A에 의해 잠기는 것이 필요합니다.

두 쿼리 모두 앞으로 진행할 수 없습니다(멕시코식 교착 상태로 간주). SQL Server는 무승부를 호출하고, 다른 쿼리를 뒤에서 쏘고, 잠금을 해제하고, 다른 쿼리가 계속 진행되도록 합니다. SQL Server는 롤백 비용이 더 적게 드는 대상을 선택합니다.원하는 경우 특정 쿼리에 대해 SET DALLOCK_PRIORITY LOW를 사용하여 대상을 뒤에 그릴 수 있으며 SQL Server가 먼저 대상을 촬영합니다.

특정 시간에 무엇이 잠겨 있는지 모니터링하고 확인할 수 있는 방법이 있습니까?

물론이죠. sys.dm _tran_dll과 같이 쿼리할 수 있는 DMV(Dynamic Management Views)가 있지만 가장 쉬운 방법은 Adam Machanic의 무료 sp_WhoIsActive 저장 프로시저를 사용하는 것입니다.이것은 다음과 같이 부를 수 있는 sp_를 대체하는 정말 교묘한 방법입니다.

sp_WhoIsActive @get_locks = 1

실행 중인 각 쿼리에 대해 모든 잠금을 설명하는 작은 XML이 제공됩니다.차단 열도 있으므로 누가 누구를 차단하는지 알 수 있습니다.보관 중인 잠금을 해석하려면 잠금 유형에 대한 온라인 설명을 확인해야 합니다.

각 스레드가 단일 테이블에서 쿼리를 수행하는 경우 차단이 발생할 수 있는 경우가 있습니까?그렇다면 조인이 있고 여러 테이블에서 동작하는 쿼리가 있을 경우에만 교착 상태가 발생할 수 있는 것이 아닌가요?

믿거나 말거나, 단일 쿼리는 실제로 자체적으로 교착 상태에 빠질 수 있으며, 예, 쿼리는 하나의 테이블에서만 교착 상태에 빠질 수 있습니다.교착 상태에 대해 더 자세히 알아보려면 예레미야 페슈카의 교착 상태에 대한 어려움을 확인하십시오.

SQL을 직접 제어할 수 있는 경우 다음을 사용하여 행 수준 잠금을 강제로 설정할 수 있습니다.

INSERT INTO WITH (ROWLOCK) MyTable(Id, BigColumn) 
VALUES(...)

다음 두 가지 답변이 도움이 될 수 있습니다.

SQL Server에서 행 수준 잠금을 강제로 적용할 수 있습니까?

엔티티 프레임워크에서 선택한 항목으로 테이블 잠금

Management Studio에서 현재 보류 중인 잠금을 보려면 서버 아래에서 Management/Activity Monitor(관리/활동 모니터)를 확인합니다.개체별 잠금 섹션이 있으므로 삽입물이 실제로 문제를 일으키고 있는지 확인할 수 있어야 합니다.

교착 상태 오류는 일반적으로 매우 빠르게 반환됩니다.잠금을 기다리는 동안 시간 초과 오류가 발생하여 교착 상태가 발생하지 않습니다.잠금 요청에서 주기를 찾아 SQL Server에서 교착 상태를 감지합니다.

제가 생각할 수 있는 최선의 답은 다음과 같습니다.사정에 따라 다르겠지.

가장 좋은 확인 방법은 연결 SPID를 찾고 SP_lock SPID를 사용하여 Tab 유형에서 잠금 모드가 X인지 확인하는 것입니다.또한 테이블 이름을 확인할 수 있습니다.SELECT OBJECT_NAME(objid)또한 아래 쿼리를 사용하여 잠금 여부를 확인하고 싶습니다.

    SELECT RESOURCE_TYPE,RESOURCE_SUBTYPE,DB_NAME(RESOURCE_DATABASE_ID) AS 'DATABASE',resource_database_id DBID,
    RESOURCE_DESCRIPTION,RESOURCE_ASSOCIATED_ENTITY_ID,REQUEST_MODE,REQUEST_SESSION_ID,
    CASE WHEN RESOURCE_TYPE = 'OBJECT' THEN OBJECT_NAME(RESOURCE_ASSOCIATED_ENTITY_ID,RESOURCE_DATABASE_ID) ELSE '' END OBJETO
    FROM SYS.DM_TRAN_LOCKS (NOLOCK)
    WHERE REQUEST_SESSION_ID = --SPID here

SQL Server 2008 이상에서는 테이블에서 잠금 에스컬레이션을 사용하지 않도록 설정하고 삽입 절에 WITH(ROWLOCK)를 적용하여 행 잠금을 효과적으로 강제할 수 있습니다.이 작업은 SQL Server 2008 이전에는 수행할 수 없습니다(ROWLOCK로 작성할 수 있지만 SQL Server는 무시하도록 선택할 수 있습니다).

저는 여기서 장군님들과 이야기를 나누고 있는데, 저는 보통 개발자들에게 특히 1MB 이상이면 BLOB를 피하라고 조언하기 때문에 BLOB에 대한 경험이 많지 않습니다.

언급URL : https://stackoverflow.com/questions/7395915/does-inserting-data-into-sql-server-lock-the-whole-table

반응형