답변:
다음은 코드 스 니펫입니다.
using System.Transactions;
....
using (var transactionScope = new TransactionScope())
{
DoYourDapperWork();
transactionScope.Complete();
}
System.Transactions
기본적으로 참조되지 않으므로 어셈블리 에 대한 참조를 추가해야합니다 .
Dispose()
방법 으로 자동으로 수행합니다 . Complete()
호출되지 않은 경우 트랜잭션이 롤백됩니다.
TransctionScope
있습니다.이 답변을 선택하는 경우 사용 블록 내부에서 연결을 열어야합니다 .
연결에서 직접 트랜잭션을 가져 오는 방식으로보다 직관적 인 접근 방식을 선호했습니다.
// 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();
}
.BeginTransaction()
Execute
필수 항목이므로 에서 매개 변수로 트랜잭션을 포함하는 것이 좋습니다.
TransactionScope
Dapper는 ADO.NET 명령 만 실행하므로 사용할 수 있어야 합니다.
using (var scope = new TransactionScope())
{
// insert
// insert
scope.Complete();
}
모든 테이블이 단일 데이터베이스에 있다는 것을 고려할 때 TransactionScope
여기에 몇 가지 답변에 제안 된 솔루션에 동의하지 않습니다 . 이 답변을 참조하십시오 .
TransactionScope
일반적으로 분산 트랜잭션에 사용됩니다. 서로 다른 데이터베이스에 걸친 트랜잭션은 서로 다른 시스템에있을 수 있습니다. 이를 위해서는 운영 체제 및 SQL Server에서 일부 구성이 필요합니다. 그렇지 않으면 작동하지 않습니다. 모든 쿼리가 단일 데이터베이스 인스턴스에 대한 경우에는 권장되지 않습니다.
그러나 단일 데이터베이스를 사용하면 제어 할 수없는 트랜잭션에 코드를 포함해야 할 때 유용 할 수 있습니다. 단일 데이터베이스를 사용하면 특별한 구성도 필요하지 않습니다.
connection.BeginTransaction
단일 데이터베이스에 대해 트랜잭션 (C #, VB.NET 등)을 구현하는 ADO.NET 구문입니다. 이것은 여러 데이터베이스에서 작동하지 않습니다.
그래서 connection.BeginTransaction()
더 나은 방법입니다.
TransactionScope
은 OP가 원하는 것에 대해 비효율적 인 사용 을 제안합니다 . 나는 그것이 TransactionScope
많은 경우에 좋은 도구 라는 데 동의합니다 . 그러나 이것은 아닙니다.
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
Dispose
첫 번째 또는 두 번째로 호출 되는 메서드 를 전달하려고 시도한 것이 아니라 두 번 호출되었습니다. "처분을 두 번 호출하는 것이 해롭지 않다"는 점에 관해서는 그것은 큰 가정입니다. 문서와 실제 구현이 종종 일치하지 않는다는 것을 배웠습니다. 하지만 마이크로 소프트의 말을 원한다면 : msdn.microsoft.com/en-us/library/…