Skip to content

Commit

Permalink
feat: an error happened in the transaction, allow one empty rollback (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
KirillKurdyukov committed Sep 25, 2024
1 parent 544c6cd commit 974ed50
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 24 deletions.
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

0 comments on commit 974ed50

Please sign in to comment.