What are the differences between calling DbConnection.EnlistTransaction and setting DbCommand.Transaction?

Viewed 206

I am trying to understand the difference between:

My understanding so far:

  • DbConnection.EnlistTransaction: is mostly about making a connection enlisted to a distributed transaction, which inherits from DbTransaction.
  • DbCommand.Transaction: is to tell in which transaction (again DbTransaction) the command is going to be executed.

So far, so good, I just quoted what the official documentation is saying.

Now my I'm wondering how both are combined... meaning:

  • DbConnection.EnlistTransaction: needs to be performed before or after opening a connection?
  • DbCommand.Transaction, if the DbConnection is enlisted to a distributed transaction and creates a DbCommand, does it mean that this command directly inherits from the connection enlisted transaction? But then what if another transaction is assigned to command, which Transaction is used upon the command execution?

EDIT

About DbConnection.EnlistTransaction: https://stackoverflow.com/a/43998009/4636721

About DbConnection.BeginTransaction, it just creates a Transaction and call the begin method which just executes (non-query) a BEGIN TRANSACTION statement. Conversely, Transaction.Commit, is sending the COMMIT statement to the backend.

For the grand sake of simplicity, I'm just using some System.Data.SQLite source code snippets to illustrate what I'm talking about:

/// <summary>
/// Attempts to start a transaction.  An exception will be thrown if the transaction cannot
/// be started for any reason.
/// </summary>
/// <param name="deferredLock">TRUE to defer the writelock, or FALSE to lock immediately</param>
protected override void Begin(bool deferredLock)
{
  if (this._cnn._transactionLevel++ != 0)
    return;
  try
  {
    using (SQLiteCommand command = this._cnn.CreateCommand())
    {
      if (!deferredLock)
        command.CommandText = "BEGIN IMMEDIATE;";
      else
        command.CommandText = "BEGIN;";
      command.ExecuteNonQuery();
    }
  }
  catch (SQLiteException ex)
  {
    --this._cnn._transactionLevel;
    this._cnn = (SQLiteConnection) null;
    throw;
  }
}

/// <summary>Commits the current transaction.</summary>
public override void Commit()
{
  this.CheckDisposed();
  this.IsValid(true);
  if (this._cnn._transactionLevel - 1 == 0)
  {
    using (SQLiteCommand command = this._cnn.CreateCommand())
    {
      command.CommandText = "COMMIT;";
      command.ExecuteNonQuery();
    }
  }
  --this._cnn._transactionLevel;
  this._cnn = (SQLiteConnection) null;
}
0 Answers
Related