2016-10-22 12 views
1

연습을 학습하고 어떤 ORM (EF와 같은)을 사용하기 전에 ADO.NET과 저장 프로 시저를 사용하여 개인 프로젝트를 만들고 싶습니다. SQL Server : 트랜잭션에서 SELECT 쿼리를 래핑하는 데 성능상의 불이익이 있습니까?

내 코드가 시간이 지남에 엉망이되고 싶어하지 않기 때문에

, 나는 저장소 및 UOW 패턴과 같은 몇 가지 패턴을 사용하고 싶습니다.

트랜잭션 처리를 제외하고는 거의 모든 것을 알아 냈습니다.

어떻게 든 '시뮬레이션'을 수행하기 위해 @jgauffin에서 제공 한 this class을 사용했지만 그 클래스를 사용하지 못하게하는 것은 해당 클래스의 새 인스턴스 (AdoNetUnitOfWork)를 만들 때마다 자동으로 트랜잭션을 시작한다는 것입니다. 그리고 당신은 단지 데이터를 읽을 필요가있는 많은 경우가 있습니다. 회전 블록에서 참조 된 테이블에 대한 잠금을 생성 할 수 있습니다 트랜잭션 내에서 SELECT 문을 실행

하는이 있습니다 :이 이와 관련

내가 SQL 책 내가 읽어 봤는데 중 하나에서 발견 된 것입니다 직장이나 데이터 읽기를 수행에서 다른 사용자 또는 세션이

이것은 AdoNetUnitOfWork 클래스 :

public class AdoNetUnitOfWork : IUnitOfWork 
{ 
    public AdoNetUnitOfWork(IDbConnection connection, bool ownsConnection) 
    { 
     _connection = connection; 
     _ownsConnection=ownsConnection; 
     _transaction = connection.BeginTransaction(); 
    } 

    public IDbCommand CreateCommand() 
    { 
     var command = _connection.CreateCommand(); 
     command.Transaction = _transaction; 
     return command; 
    } 

    public void SaveChanges() 
    { 
     if (_transaction == null) 
      throw new InvalidOperationException("Transaction have already been commited. Check your transaction handling."); 

     _transaction.Commit(); 
     _transaction = null; 
    } 

    public void Dispose() 
    { 
     if (_transaction != null) 
     { 
      _transaction.Rollback(); 
      _transaction = null; 
     } 

     if (_connection != null && _ownsConnection) 
     { 
      _connection.Close(); 
      _connection = null; 
     } 
    } 
} 

그리고 이것은 내가 내 저장소에 UOW를 사용하는 방법입니다 : 내가 트랜잭션이 선택 될 수 있도록이 코드를 조금 조정할 수있어

public DomainTable Get(int id) 
{ 
    DomainTable table; 

    using (var commandTable = _unitOfWork.CreateCommand()) 
    { 
     commandTable.CommandType = CommandType.StoredProcedure; 
     //This stored procedure contains just a simple SELECT statement 
     commandTable.CommandText = "up_DomainTable_GetById"; 

     commandTable.Parameters.Add(commandTable.CreateParameter("@pId", id)); 

     table = ToList(commandTable).FirstOrDefault(); 
    } 

    return table; 
} 

,하지만 난 가능한 한 독립적 인 플랫폼으로이 코드를 만들려고 노력하기 때문에 그리고 내가 EF와 같은 다른 퍼시스턴스 프레임 워크에서 알고있는 한 수동으로 트랜잭션을 관리 할 필요는 없습니다. 문제는이 클래스를 그대로 사용하여 병목 현상을 만들 것인지, 트랜잭션을 항상 생성하는지 여부입니다 ?

+1

http://dba.stackexchange.com/questions/43254/is-it-a-bad-practice-to-always-create-a-transaction https://social.msdn.microsoft.com/Forums/ sqlserver/ko-US/18a09050-79a8-4c83-99e6-1335a14604e0/왜 줄 바꿈 - 선택 - 성명서 - 거래에서 포럼 = transactsql –

답변

6

그것은 모두 transaction isolation level에 따라 달라집니다. 기본 격리 수준 (즉, 읽기 커밋)을 사용하면 SELECT은 트랜잭션에 래핑 된 경우 성능 저하가 없어야합니다. SQL Server는 이미 시작되지 않은 경우 트랜잭션의 문을 내부적으로 래핑하므로 코드가 거의 동일하게 동작해야합니다. 하지가 사용하는 이유

그러나, 나는 당신을 요청해야합니다 내장 된 닷넷 TransactionScope? 이렇게하면 TransactionScope이 보편적으로 사용되기 때문에 코드가 다른 라이브러리 및 프레임 워크와 훨씬 잘 상호 작용합니다. 이 스위치로 전환하기로 결정한 경우 기본적으로 TransactionScope은 SERIALIZABLE 격리 수준을 사용하므로 성능이 저하됩니다 (using new TransactionScope() Considered Harmful 참조).

+0

감사합니다 @ 나머지. 또한 ** 기본적으로 ** SQL은 모든 문에 대해 내부적으로 트랜잭션을 작성하지만 다른 소스에서는이를 확인할 수있는 소스를 찾을 수 없었습니다. 내가 왜'TransactionScope'를 사용하지 않았는지에 관해서는, 약간의 시간 동안 나는 데이터베이스에 대해 읽었고 C#을 처음 들어 봤다. (나는 프론트 엔드 개발자이다. 백엔드 세계로 나아 가기 위해). 그러나 그것은 흥미있는 것으로 들린다. – eddy

+0

저는 모든 프로젝트가 다르다는 것을 알고 있습니다 만, 당신이 경험 한 것을 기초로, 당신에게 가장 유용한 것으로 입증 된 격리 수준의 유형이나 새 프로젝트를 시작할 때마다 당신이 보통 가지고있는 격리 수준의 유형을 알고 있습니까? – eddy

+0

특별한 이유가 없으면 커밋 된 읽기 상태로 두겠습니다. –