0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ADO.NET の非同期トランザクション

Last updated at Posted at 2023-06-02

DbConnectionクラスのメソッドが色々と非同期になっているので、トランザクションを非同期で実装する例

参考:MSDN

通常のトランザクション

  • 先ずは「同期」でトランザクションを行うメソッド
    • 処理内容はfuncとして外部から指定できるように
public static TResult Transact<TResult>(DbConnection connection, IsolationLevel isolationLevel, Func<DbTransaction, TResult> func)
{
  connection.Open();
  try
  {
    using var transaction = connection.BeginTransaction(isolationLevel);
    try
    {
      var result = func(transaction);
      transaction.Commit();
      return result;
    }
    catch
    {
      transaction.Rollback();
      throw;
    }
  }
  finally
  {
    connection.Close();
  }
}

非同期トランザクション

  • 上記メソッドを「非同期」に変更
    • Func<DbTransaction, TResult> func
    • Func<DbTransaction, Task<TResult>> funcAsyncに変更
public static async Task<TResult> TransactAsync<TResult>(DbConnection connection, IsolationLevel isolationLevel, Func<DbTransaction, Task<TResult>> funcAsync)
{
  await connection.OpenAsync();
  try
  {
    using var transaction = await connection.BeginTransactionAsync(isolationLevel);
    try
    {
      var result = await funcAsync(transaction);
      await transaction.CommitAsync();
      return result;
    }
    catch
    {
      await transaction.RollbackAsync();
      throw;
    }
  }
  finally
  {
    await connection.CloseAsync();
  }
}

使用例

  • 通常と非同期トランザクションのそれぞれの呼び出し方
string TestTransaction()
{
  using var connection = new SqlConnection("接続文字列");
  return Transact(connection, IsolationLevel.ReadCommitted, transaction =>
  {
    using var select = transaction.Connection.CreateCommand();
    select.CommandText = "SELECT id FROM table";
    var result = select.ExecuteScalar();
    return (string)result;
  });
}

async Task<string> TestTransactionAsync()
{
  using var connection = new SqlConnection("接続文字列");
  return await TransactAsync(connection, IsolationLevel.ReadCommitted, async transaction =>
  {
    using var select = transaction.Connection.CreateCommand();
    select.CommandText = "SELECT id FROM table";
    var result = await select.ExecuteScalarAsync();
    return (string)result;
  });
}
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?