Skip to content
Permalink
Browse files

Completely ignore DbCommand.Transaction

PostgreSQL only supports a single transaction on a given connection at
a given time; as a result, Npgsql largely ignores DbCommand.Transaction.
This commit removes some useless partial checks.

Also disable related specification tests (part of #225).
  • Loading branch information...
roji committed Apr 11, 2019
1 parent f52e1a5 commit 0321a5af01d0252520570ac000fb7be056de5831
@@ -40,7 +40,6 @@ public sealed class NpgsqlCommand : DbCommand, ICloneable
[CanBeNull]
NpgsqlConnector _connectorPreparedOn;

NpgsqlTransaction _transaction;
string _commandText;
int? _timeout;
readonly NpgsqlParameterCollection _parameters;
@@ -184,19 +183,7 @@ public new NpgsqlConnection Connection
set
{
if (_connection == value)
{
return;
}

//if (this._transaction != null && this._transaction.Connection == null)
// this._transaction = null;

// All this checking needs revising. It should be simpler.
// This this.Connector != null check was added to remove the NullReferenceException in case
// of the previous connection has been closed which makes Connector null and so the last check would fail.
// See bug 1000581 for more details.
if (_transaction != null && _connection != null && _connection.Connector != null && _connection.Connector.InTransaction)
throw new InvalidOperationException("The Connection property can't be changed with an uncommited transaction.");

_connection = State == CommandState.Idle
? value
@@ -1193,27 +1180,15 @@ async ValueTask<DbDataReader> ExecuteDbDataReader(CommandBehavior behavior, bool
protected override DbTransaction DbTransaction
{
get => Transaction;
set => Transaction = (NpgsqlTransaction) value;
set => Transaction = (NpgsqlTransaction)value;
}

/// <summary>
/// Gets or sets the <see cref="NpgsqlTransaction">NpgsqlTransaction</see>
/// within which the <see cref="NpgsqlCommand">NpgsqlCommand</see> executes.
/// This property is ignored by Npgsql. PostgreSQL only supports a single transaction at a given time on
/// a given connection, and all commands implicitly run inside the current transaction started via
/// <see cref="NpgsqlConnection.BeginTransaction()"/>
/// </summary>
/// <value>The <see cref="NpgsqlTransaction">NpgsqlTransaction</see>.
/// The default value is a null reference.</value>
public new NpgsqlTransaction Transaction
{
get
{
if (_transaction != null && _transaction.Connection == null)
{
_transaction = null;
}
return _transaction;
}
set => _transaction = value;
}
public new NpgsqlTransaction Transaction { get; set; }

#endregion Transactions

@@ -1246,7 +1221,7 @@ protected override void Dispose(bool disposing)
{
if (State == CommandState.Disposed)
return;
_transaction = null;
Transaction = null;
_connection = null;
State = CommandState.Disposed;
base.Dispose(disposing);
@@ -8,5 +8,10 @@ public NpgsqlCommandTests(NpgsqlDbFactoryFixture fixture)
: base(fixture)
{
}

// PostgreSQL only supports a single transaction on a given connection at a given time. As a result,
// Npgsql completely ignores DbCommand.Transaction.
public override void ExecuteReader_throws_when_transaction_required() {}
public override void ExecuteReader_throws_when_transaction_mismatched() {}
}
}
@@ -631,9 +631,9 @@ public void ConnectorNotInitializedException1000581()
{
connection.Open();
command.Connection = connection;
command.Transaction = connection.BeginTransaction();
var tx = connection.BeginTransaction();
command.ExecuteScalar();
command.Transaction.Commit();
tx.Commit();
}
}
}

0 comments on commit 0321a5a

Please sign in to comment.
You can’t perform that action at this time.