I am trying to understand the difference between:
DbConnection.EnlistTransaction(and related bits of info)DbCommand.TransactionDbTransactionwhich is either something you get from callingDbConnection.BeginTransactionor Transaction.Current
My understanding so far:
DbConnection.EnlistTransaction: is mostly about making a connection enlisted to a distributed transaction, which inherits fromDbTransaction.DbCommand.Transaction: is to tell in which transaction (againDbTransaction) 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 theDbConnectionis enlisted to a distributed transaction and creates aDbCommand, 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;
}