Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
- If an error happened in the transaction, allow one empty rollback

## v0.7.0
- Parsed @param then prepared for use with $ prefix (@p -> $p)
- Fully integrated with Dapper
Expand Down
18 changes: 2 additions & 16 deletions src/Ydb.Sdk/src/Ado/YdbCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ protected override DbTransaction? DbTransaction
{
if (value is null or YdbTransaction)
{
_ydbTransaction = (YdbTransaction?)value;
Transaction = (YdbTransaction?)value;
}
else
{
Expand All @@ -132,21 +132,7 @@ protected override DbTransaction? DbTransaction
}
}

public new YdbTransaction? Transaction
{
get
{
if (_ydbTransaction?.Completed ?? false)
{
_ydbTransaction = null;
}

return _ydbTransaction;
}
set => _ydbTransaction = value;
}

private YdbTransaction? _ydbTransaction;
public new YdbTransaction? Transaction { get; set; }

public override bool DesignTimeVisible { get; set; }

Expand Down
2 changes: 1 addition & 1 deletion src/Ydb.Sdk/src/Ado/YdbDataReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@ private void OnFailReadStream()
ReaderState = State.Closed;
if (_ydbTransaction != null)
{
_ydbTransaction.Completed = true;
_ydbTransaction.Failed = true;
}
}

Expand Down
29 changes: 25 additions & 4 deletions src/Ydb.Sdk/src/Ado/YdbTransaction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,26 @@ public sealed class YdbTransaction : DbTransaction
{
private readonly TxMode _txMode;

private bool _failed;

internal string? TxId { get; set; }
internal bool Completed { get; set; }
internal bool Completed { get; private set; }

internal bool Failed
{
private get => _failed;
set
{
_failed = value;
Completed = true;
}
}

internal TransactionControl TransactionControl => TxId == null
? new TransactionControl { BeginTx = _txMode.TransactionSettings() }
: new TransactionControl { TxId = TxId };
internal TransactionControl? TransactionControl => Completed
? null
: TxId == null
? new TransactionControl { BeginTx = _txMode.TransactionSettings() }
: new TransactionControl { TxId = TxId };

internal YdbTransaction(YdbConnection ydbConnection, TxMode txMode)
{
Expand All @@ -41,6 +55,13 @@ public override void Rollback()
// TODO propagate cancellation token
public override async Task RollbackAsync(CancellationToken cancellationToken = new())
{
if (Failed)
{
Failed = false;

return;
}

await FinishTransaction(txId => DbConnection.Session.RollbackTransaction(txId));
}

Expand Down
10 changes: 9 additions & 1 deletion src/Ydb.Sdk/tests/Ado/YdbExceptionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public async Task IsTransient_WhenSchemaError_ReturnFalse()
}

[Fact]
public async Task IsTransient_WhenAborted_ReturnTrue()
public async Task IsTransient_WhenAborted_ReturnTrueAndMakeEmptyRollback()
{
var bankTable = $"Bank_{Utils.Net}";
await using var ydbConnection = new YdbConnection();
Expand Down Expand Up @@ -57,5 +57,13 @@ public async Task IsTransient_WhenAborted_ReturnTrue()
{
CommandText = $"DROP TABLE {bankTable}"
}.ExecuteNonQueryAsync();
Assert.Equal("This YdbTransaction has completed; it is no longer usable",
Assert.Throws<InvalidOperationException>(() => ydbCommand.Transaction.Commit()).Message);

await ydbCommand.Transaction!.RollbackAsync();
Assert.Equal("This YdbTransaction has completed; it is no longer usable",
Assert.Throws<InvalidOperationException>(() => ydbCommand.Transaction!.Commit()).Message);
Assert.Equal("This YdbTransaction has completed; it is no longer usable",
Assert.Throws<InvalidOperationException>(() => ydbCommand.Transaction!.Rollback()).Message);
}
}
25 changes: 23 additions & 2 deletions src/Ydb.Sdk/tests/Ado/YdbTransactionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public void Commit_WhenEmptyYdbCommand_DoNothing()
}

[Fact]
public void Commit_WhenDoubleCommit_ThrowException()
public void CommitAndRollback_WhenDoubleCommit_ThrowException()
{
using var connection = new YdbConnection();
connection.Open();
Expand Down Expand Up @@ -165,7 +165,7 @@ public void CommitAndRollback_WhenConnectionIsClosed_ThrowException()
}

[Fact]
public void Commit_WhenConnectionIsClosedAndTxDoesNotStarted_ThrowException()
public void CommitAndRollback_WhenConnectionIsClosedAndTxDoesNotStarted_ThrowException()
{
using var connection = new YdbConnection();
connection.Open();
Expand All @@ -179,6 +179,27 @@ public void Commit_WhenConnectionIsClosedAndTxDoesNotStarted_ThrowException()
Assert.Throws<InvalidOperationException>(() => ydbTransaction.Rollback()).Message);
}

[Fact]
public void CommitAndRollback_WhenTransactionIsFailed_ThrowException()
{
using var connection = new YdbConnection();
connection.Open();

var ydbCommand = connection.CreateCommand();
ydbCommand.Transaction = connection.BeginTransaction();
ydbCommand.Transaction.Failed = true;
ydbCommand.Transaction.TxId = "no_tx";

Assert.Equal("This YdbTransaction has completed; it is no longer usable",
Assert.Throws<InvalidOperationException>(() => ydbCommand.Transaction.Commit()).Message);

ydbCommand.Transaction.Rollback(); // Make completed
Assert.Equal("This YdbTransaction has completed; it is no longer usable",
Assert.Throws<InvalidOperationException>(() => ydbCommand.Transaction.Commit()).Message);
Assert.Equal("This YdbTransaction has completed; it is no longer usable",
Assert.Throws<InvalidOperationException>(() => ydbCommand.Transaction.Rollback()).Message);
}

public async Task InitializeAsync()
{
await using var connection = new YdbConnection();
Expand Down
Loading