Как использовать транзакции с dapper.net?

Я хотел бы запустить несколько операторов вставки для нескольких таблиц. Я использую dapper.net. Я не вижу возможности обрабатывать транзакции с помощью dapper.net.

Поделитесь своими идеями о том, как использовать транзакции с dapper.net.

Ответ 1

Здесь фрагмент кода:

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

Обратите внимание, что вам нужно добавить ссылку на сборку System.Transactions, потому что по умолчанию она не ссылается.

Ответ 2

Я предпочел использовать более интуитивный подход, получая транзакцию непосредственно из соединения:

// This called method will get a connection, and open it if it 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();
}

Ответ 3

Вы должны иметь возможность использовать TransactionScope, поскольку Dapper запускает только команды ADO.NET.

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

Ответ 4

Учитывая, что все ваши таблицы находятся в одной базе данных, я не согласен с решением TransactionScope предложенным в некоторых ответах здесь. Ссылайтесь на этот ответ.

  1. TransactionScope обычно используется для распределенных транзакций; транзакции, охватывающие разные базы данных, могут находиться в разных системах. Для этого нужны некоторые конфигурации в операционной системе и SQL Server, без которых это не будет работать. Это не рекомендуется, если все ваши запросы относятся к одному экземпляру базы данных.
    Но с одной базой данных это может быть полезно, когда вам нужно включить код в транзакцию, которая не находится под вашим контролем. С единой базой данных она также не требует специальных настроек.

  2. connection.BeginTransaction - это синтаксис ADO.NET для реализации транзакции (в С#, VB.NET и т.д.) для одной базы данных. Это не работает в нескольких базах данных.

Таким образом, connection.BeginTransaction() - лучший путь.

Даже лучший способ обработать транзакцию - реализовать UnitOfWork, как описано в этом ответе.

Ответ 5

Даниэль ответил, как и ожидалось для меня. Для полноты, здесь фрагмент, демонстрирующий фиксацию и откат с использованием области транзакции и 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