[c#] dapper.net에서 트랜잭션을 사용하는 방법은 무엇입니까?

여러 테이블에서 여러 삽입 문을 실행하고 싶습니다. dapper.net을 사용하고 있습니다. dapper.net으로 트랜잭션을 처리 할 방법이 없습니다.

dapper.net에서 거래를 사용하는 방법에 대한 아이디어를 공유하십시오.



답변

다음은 코드 스 니펫입니다.

using System.Transactions;
....
using (var transactionScope = new TransactionScope())
{
    DoYourDapperWork();
    transactionScope.Complete();
}

System.Transactions기본적으로 참조되지 않으므로 어셈블리 에 대한 참조를 추가해야합니다 .


답변

연결에서 직접 트랜잭션을 가져 오는 방식으로보다 직관적 인 접근 방식을 선호했습니다.

// This called method will get a connection, and open it if it's not yet open.
using (var connection = GetOpenConnection())
using (var transaction = connection.BeginTransaction())
{
    connection.Execute(
        "INSERT INTO data(Foo, Bar) values (@Foo, @Bar);", listOf5000Items, transaction);
    transaction.Commit();
}


답변

TransactionScopeDapper는 ADO.NET 명령 만 실행하므로 사용할 수 있어야 합니다.

using (var scope = new TransactionScope())
{
   // insert
   // insert
   scope.Complete();
}


답변

모든 테이블이 단일 데이터베이스에 있다는 것을 고려할 때 TransactionScope여기에 몇 가지 답변에 제안 된 솔루션에 동의하지 않습니다 . 답변을 참조하십시오 .

  1. TransactionScope일반적으로 분산 트랜잭션에 사용됩니다. 서로 다른 데이터베이스에 걸친 트랜잭션은 서로 다른 시스템에있을 수 있습니다. 이를 위해서는 운영 체제 및 SQL Server에서 일부 구성이 필요합니다. 그렇지 않으면 작동하지 않습니다. 모든 쿼리가 단일 데이터베이스 인스턴스에 대한 경우에는 권장되지 않습니다.
    그러나 단일 데이터베이스를 사용하면 제어 할 수없는 트랜잭션에 코드를 포함해야 할 때 유용 할 수 있습니다. 단일 데이터베이스를 사용하면 특별한 구성도 필요하지 않습니다.

  2. connection.BeginTransaction단일 데이터베이스에 대해 트랜잭션 (C #, VB.NET 등)을 구현하는 ADO.NET 구문입니다. 이것은 여러 데이터베이스에서 작동하지 않습니다.

그래서 connection.BeginTransaction()더 나은 방법입니다.

트랜잭션을 처리하는 더 좋은 방법은 답변 에서 설명한대로 UnitOfWork를 구현 하는 것입니다.


답변

Daniel의 대답은 예상대로 작동했습니다. 완전성을 위해 트랜잭션 범위와 dapper를 사용하여 커밋 및 롤백을 보여주는 스 니펫은 다음과 같습니다.

using System.Transactions;
    // _sqlConnection has been opened elsewhere in preceeding code 
    using (var transactionScope = new TransactionScope())
    {
        try
        {
            long result = _sqlConnection.ExecuteScalar<long>(sqlString, new {Param1 = 1, Param2 = "string"});

            transactionScope.Complete();
        }
        catch (Exception exception)
        {
            // Logger initialized elsewhere in code
            _logger.Error(exception, $"Error encountered whilst executing  SQL: {sqlString}, Message: {exception.Message}")

            // re-throw to let the caller know
            throw;
        }
    } // This is where Dispose is called 


답변