SqlConnection / System.Transactions를 사용하여 요청 당 세션 수

dapper sqlconnection sql-server system.transactions

문제

나는 Dapper를 프로젝트에 사용하기 시작했다. 지난 몇 년간 NHibernate와 EF 같은 ORM을 주로 사용했다.

일반적으로 웹 응용 프로그램에서는 요청 당 세션을 구현하고 요청을 시작할 때 트랜잭션을 시작하고 끝에 커밋합니다.

SqlConnection / System.Transactions로 직접 작업 할 때 비슷한 작업을 수행해야합니까?

StackOverflow는 어떻게합니까?

해결책

@gbn과 @Sam Safron 모두의 조언을 받아서 나는 트랜잭션을 사용하지 않는다. 내 경우에는 읽기 쿼리 만 수행하므로 암시 적 트랜잭션에 대해 말한 것과는 달리 트랜잭션을 사용하기위한 실제 요구 사항이없는 것처럼 보입니다.

내가 요청 당 연결을 사용할 수 있도록 간단한 세션 인터페이스를 만듭니다. 이것은 Dapper와 마찬가지로 나에게 상당히 유익합니다. 종종 객체를 빌드하기 위해 몇 가지 다른 쿼리를 만들어야하고 동일한 연결을 공유하려고합니다.

요청마다 연결 범위를 지정하고 처리하는 작업은 IoC 컨테이너 (StructureMap)에서 수행합니다.

public interface ISession : IDisposable {
    IDbConnection Connection { get; }
}

public class DbSession : ISession {

    private static readonly object @lock = new object();
    private readonly ILogger logger;
    private readonly string connectionString;
    private IDbConnection cn;

    public DbSession(string connectionString, ILogger logger) {
        this.connectionString = connectionString;
        this.logger = logger;
    }

    public IDbConnection Connection { get { return GetConnection(); } }

    private IDbConnection GetConnection() {
        if (cn == null) {
            lock (@lock) {
                if (cn == null) {
                    logger.Debug("Creating Connection");
                    cn = new SqlConnection(connectionString);
                    cn.Open();
                    logger.Debug("Opened Connection");
                }
            }
        }

        return cn;
    }

    public void Dispose() {
        if (cn != null) {
            logger.Debug("Disposing connection (current state '{0}')", cn.State);
            cn.Dispose();
        }
    }
}

수락 된 답변

이것이 우리가하는 일입니다.

우리는 Current 라는 객체에 DB 라는 정적을 정의합니다.

   protected void Application_EndRequest(object sender, EventArgs e)
   {
        Current.DisposeDB(); // closes connection, clears context 
   }

우리의 경우 InstantiateDB 는 L2S 컨텍스트를 반환하지만, 열려있는 SQLConnection 또는 다른 것이 될 수 있습니다.

응용 프로그램 객체에서 우리는 요청이 끝날 때 연결이 끊어 졌는지 확인합니다.

   protected void Application_EndRequest(object sender, EventArgs e)
   {
        Current.DisposeDB(); // closes connection, clears context 
   }

그렇다면 어디서나 코드에 액세스 할 필요가있는 db에 간단하게 Current.DB 호출하면 자동으로 작동합니다. 이것은 #if DEBUG 때문에 단위 테스트에도 친숙합니다.


우리는 세션 당 트랜잭션을 시작하지 않습니다. 세션이 시작될 때 업데이트를 수행했다면 잠금이 해제 될 때까지 잠금이 해제되지 않으므로 심각한 잠금 문제가 발생합니다.


인기 답변

"쓰기"호출로 데이터베이스를 호출 할 때 TransactionScope 와 같은 것을 사용해야 할 때만 SQL Server 트랜잭션을 시작할 수 있습니다.

이 최근 질문에서 임의의 예를 참조하십시오. TransactionScope.Complete ()가 호출되지 않아도 중첩 된 트랜잭션이 커밋되는 이유는 무엇입니까?

연결을 열고 http 요청 당 트랜잭션을 시작 하지 않을 것 입니다. 필요시에만. 나는 어려움을 이해하는 데 왜 세션 당 데이터베이스 트랜잭션을 열고 일부 민속 옹호 : 깎아 지른듯한 바보 같은 당신은 데이터베이스 트랜잭션이 무엇인지를 볼 때

참고 : 본인의 본성에 위배되지 않습니다. MSDTC를 호출하는 불필요하고 긴 클라이언트 측 데이터베이스 트랜잭션에 반대합니다.




아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.