Dapper.IDbConnection을 사용하여 BeginTransaction을 사용하는 올바른 방법

.net c# dapper idbconnection orm

문제

Dapper에서 BeginTransaction()IDbConnection 과 함께 사용하는 올바른 방법은 무엇입니까?

BeginTransaction() 을 사용해야하는 메서드를 만들었습니다. 여기에 코드가 있습니다.

using (IDbConnection cn = DBConnection)
{
    var oTransaction = cn.BeginTransaction();

    try
    {
        // SAVE BASIC CONSULT DETAIL
        var oPara = new DynamicParameters();
        oPara.Add("@PatientID", iPatientID, dbType: DbType.Int32);
        ..........blah......blah............
    }
    catch (Exception ex)
    {
        oTransaction.Rollback();
        return new SaveResponse { Success = false, ResponseString = ex.Message };
    }
}

위의 메서드를 실행할 때 - 예외가 발생했습니다 -

잘못된 작업입니다. 연결이 닫힙니다.

이는 연결이 열리기 전에 트랜잭션을 시작할 수 없기 때문입니다. 그래서이 줄을 추가 할 때 : cn.Open(); 오류가 해결됩니다. 하지만 어딘가 수동으로 연결을 여는 것은 나쁜 습관입니다 !! Dapper는 필요할 때만 연결을 엽니 다.

Entity 프레임 워크에서 TransactionScope 사용하여 TransactionScope 처리 할 수 ​​있습니다.

그래서 제 질문은 cn.Open()...Dapper에 추가하지 않고 트랜잭션을 처리하는 좋은 방법입니까? 나는 이것을 위해 적절한 방법이 있어야한다고 생각합니다.

수락 된 답변

수동으로 연결을 여는 것은 "나쁜 습관"이 아닙니다. 더퍼는 편리함으로 열린 연결 또는 닫힌 연결 작동합니다. 일반적인 잡았다는 사람들을 풀어 놓지 않고 너무 오랫동안 열어 놓고 사용하지 않은 상태로 남겨두고 있습니다. 그러나 이것은 대부분의 경우 문제가되지 않으며 확실히 할 수 있습니다.

using(var cn = CreateConnection()) {
    cn.Open();
    using(var tran = cn.BeginTransaction()) {
        try {
            // multiple operations involving cn and tran here

            tran.Commit();
        } catch {
            tran.Rollback();
            throw;
        }
    }
}

dapper에는 트랜잭션에서 전달할 선택적 매개 변수가 있습니다 (예 :

cn.Execute(sql, args, transaction: tran);

사실에 대한 확장 메서드 만들기 위해 유혹입니다 IDbTransaction 때문에, 유사하게 작동 트랜잭션이 항상 노출 .Connection ; 이것은 허용 할 것이다 :

tran.Execute(sql, args);

그러나 이것은 오늘날 존재하지 않습니다.

TransactionScope 는 또 다른 옵션이지만 다른 의미가 있습니다. LTM 또는 DTC가 포함될 수 있습니다 ... 주로 행운을 빕니다. 또한 try / catch 가 필요없는 IDbTransaction 대한 래퍼를 만들 try - TransactionScope 작동 방식에 더 IDbTransaction . 뭔가 (이것도 존재하지 않습니다) :

using(var cn = CreateConnection())
using(var tran = cn.SimpleTransaction())
{
    tran.Execute(...);
    tran.Execute(...);

    tran.Complete();
}

인기 답변

너는 전화해서는 안된다.

cn.Close();

using 블록도 닫으려고하기 때문입니다. 트랜잭션 부분에 대해서는 Entity Framework 관련 기술이 아니기 때문에 TransactionScope를 사용할 수도 있습니다. 이 SO 응답을보십시오 : https://stackoverflow.com/a/6874617/566608 트랜잭션 범위에서 연결을 등록하는 방법을 설명합니다. 중요한 측면은 다음 과 같습니다 . 연결이 자동으로 트랜잭션에 등록됩니다 . 범위 내에서 연결을 엽니 다 .



아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow