2012-02-29 2 views
7

SqlTransaction을 C#으로 시작하여 트랜잭션을 커밋하고 롤백했습니다. 모든 것이 바르게 진행되고 있지만 트랜잭션 중에 연결되어있는 테이블에 액세스하는 동안 문제가 발생합니다. 트랜잭션 중에 테이블을 읽을 수 없습니다 (트랜잭션에있는 테이블). 이것에 대해 검색하는 동안, 나는 독점적 인 자물쇠 때문에 그것이 일어난 것을 발견했습니다. 해당 데이터에 대한 후속 선택은 독점 잠금이 해제 될 때까지 기다려야합니다. 그런 다음 SqlTransaction에 제공된 모든 격리 수준을 통과했지만 작동하지 않았습니다. 그래서 다른 사용자가 해당 테이블에 액세스하여 데이터를 읽을 수 있도록 트랜잭션 중 독점 잠금을 해제해야합니다. 이것을 수행 할 수있는 방법이 있습니까? 미리 감사드립니다. Sql 트랜잭션의 격리 수준

다음은이 코드는 잘 작동 거래

try 
{ 
    SqlTransaction transaction = null;       
    using (SqlConnection connection=new SqlConnection(Connection.ConnectionString)) 
    { 
     connection.Open(); 
     transaction=connection.BeginTransaction(IsolationLevel.Snapshot,"FaresheetTransaction");    
     //Here all transaction occurs 
     if (transaction.Connection != null) 
     {  
       transaction.Commit(); 
       transaction.Dispose(); 
     } 
    } 
} 
catch (Exception ex) 
{ 
    if (transaction.Connection != null) 
     transaction.Rollback(); 
    transaction.Dispose(); 
} `       

내 C# 코드,하지만 문제는 내가 트랜잭션의 시간 동안 테이블의 데이터 (트랜잭션 중에 액세스하는)에 액세스 할 때. 테이블은 응용 프로그램의 다른 부분에서 액세스하고 있습니다. 그래서 테이블에서 데이터를 읽으려고하면 예외가 발생합니다.

+1

? 또는 다른 독자가 자물쇠를 무시할 수 있습니까? (아주 좋은 이유로 거기에) –

+1

나는 다른 사용자를 위해 거래 테이블에 자물쇠를 갖고 싶지 않아 .... 트랜잭션은 트랜잭션의 시간이 오래 걸릴 수 있기 때문에, 수십만 데이터가 테이블에 삽입되므로 시간이 오래 걸릴 것입니다 ... 그래서, tran 기간에 saction, 나는 다른 사용자가 그 테이블에 액세스 할 수 있기를 원하고 데이터를 읽을 수 있습니다 ....... –

답변

14

SQL 트랜잭션은 의도적으로 ACID입니다. 특히 "I"는 여기에서 당신을 해치고 있습니다 - 으로 설계되어 다른 연결이 일관성없는 중간 상태를 보지 못하게합니다.

개인 독서 연결은 NOLOCK 힌트, 또는 READ UNCOMMITTED 분리 레벨을 사용하여이 규칙을 무시하도록 선택할 수 있습니다,하지만 당신은 가 잠금을지지하는 연결을 작성하기위한 것입니다 원하는 것 같은데. 글쎄, 그건 일어나지 않을거야. 독자가보고 (잠금을 복용 독자없이 격리를 달성 스냅 샷 격리를 사용하는 이름, 일관된 상태의 시점 shapshot을 알 수 있듯이

그러나, 무엇 도움이된다 트랜잭션이 시작될 때).스테이징 테이블에서 작업을 수행하는 작가

  • 에서

    • 복수,보다 세분화 된 트랜잭션 (데이터의 병렬 복사본) :

      는하지만, IMO 당신은 더 나은 하나를보고 조언 할 것 다음, 몇 대량 삽입/업데이트/삭제 작업에 실제 데이터로 그 합병 거래 시간

    을 최소화 첫 번째는 간단하다.

    간단한 사실은 많은 데이터에서 작동하는 장기 실행 트랜잭션을 수행하는 경우 이 문제를 일으킬 것이라는 점입니다. 그래서 당신은 하지 마십시오 그. 시스템이 올바르게 작동하고 있습니다.

  • +2

    두 번째 솔루션은 스냅 숏 격리가 사용되는 경우 스냅 숏 격리가 수행하는 작업과 거의 같습니다. 쓰기를 수행하는 트랜잭션의 경우) – ntziolis

    +0

    스냅 샷 격리 수준을 사용했지만 다시 동일한 문제가 발생합니다.실제로 "select * from tbl_name (nolock)"을 사용할 때 작동하지만이 선택은 다음과 같은 이유로 적합하지 않습니다. 1. 이미 커밋 된 트랜잭션의 데이터를 표시합니다. 2. 테이블이 이미 애플리케이션에서 쿼리를 받았기 때문에 코드에서 모든 쿼리를 수행하고 변경하는 것이 실현 가능하지 않습니다 ...... –

    +1

    @ akash88 스냅 샷 격리를 사용해야하는 ** 독자 **입니다. 도움이되지 않으면 스냅 샷 격리를 활성화하지 않았는지 궁금합니다. 근본적으로, 당신은 시스템에 반대하는 무언가를하려고 노력하고 있습니다. 예를 들면 다음과 같습니다. "큰 덩어리를 재 작성하는 동안 큰 파일을 열었습니다. 독자가 진행중인 편집을 볼 수 있기 때문에 공유 액세스를 허용하고 싶지는 않지만 닫을 때까지 파일이 잠겨 있지 않습니다. 이걸 어떻게 수정해야합니까? " 대답 : 당신은하지 않습니다; 당신은 시스템을 다르게 설계합니다. –

    3

    트랜잭션 내에서 읽기를 실행하고 격리 수준 READ UNCOMMITTED을 사용해보십시오. 이 고정되는 것을 읽기를 방지 할 수 있지만 유효하지 않은 결과가 발생할 수 있습니다 : 오해가 실제로는 읽을 때 동등하게 중요 할 때, 기록 할 때 트랜잭션 처리/격리 수준은 중요한 것이있다

    SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED  
    BEGIN TRANSACTION 
    
    SELECT * FROM Table 
    
    COMMIT TRANSACTION 
    

    .

    +0

    응답 해 주셔서 감사합니다 ..... 나는 모든 유형의 격리 수준을 사용했지만 내 시나리오에서는 해결할 수있었습니다. .. 실제로, 나는 C#에서 BeginTransaction() 메서드를 사용하여 SqlTransaction ....을 사용하고 있습니다. 트랜잭션에서 문제가되는 테이블에 대해 다른 사용자에게 액세스 권한을 부여하려고합니다 ..... 그러나 모든 격리 수준에서 배타적입니다. 잠금이 진행 중입니다 ........ –

    +0

    테이블에 쓰려면 독점 잠금이 필요합니다. 단 하나의 예외는 격리 수준 스냅 샷을 사용할 때이지만, SQL 2008에서 시작하는 경우에만 사용할 수 있다는 것입니다. 따라서 읽음을 허용하는 유일한 방법은 위에 설명 된대로 읽지 않은 상태에서 읽기 또는 비 혼돈 격리 수준을 사용하는 것입니다. – ntziolis

    +0

    스냅 샷 격리는 이미 SQL 2005에서 사용할 수 있으므로 스냅 샷을 사용할 수 있습니다. 작성시 스냅 샷 격리를 사용하면 잘 수행해야합니다. 당신은 다른 작업에서 독서하는 것처럼 보이기 때문에 문제가 없어야합니다. – ntziolis

    2

    문제는 데이터베이스에 쓰는 수준이 아니라 읽기 값의 수준에 있습니다. 삽입중인 값을 읽으려고합니다. 선택 쿼리를 다음으로 변경하십시오.

    select * from your_table_with_inserts with (nolock) 
    

    그러나이 옵션은 현재 트랜잭션의 격리 수준보다 우선하며 더티 읽기를 유발할 수 있습니다.

    질문 : 모든 쿼리에서 트랜잭션을 사용하거나 삽입/업데이트 만하는 경우?

    1

    @ AKASH88, SNAPSHOT 격리 수준이 당신이 찾고있는 것입니다.

    SNAPSHOT이 예상대로 작동하지 않는 경우에도 배타적 잠금이 발생합니다. 동일한 문제가 있다는 것을 이해할 수 있습니다.

    데이터베이스 옵션에서 SNAPSHOT을 활성화하지 말고 READ COMMITTED SNAPSHOT도 켜야합니다.

    enter image description here

    ! 이것은 SQL 서버 2008, 그래서이 답변 :(

    감사합니다 도움이 될 것입니다 경우 여전히 불확실 당신의 의도가 여기에 무엇? 업데이트 할 때 아니오 잠금을하지

    관련 문제