Skip to content

Commit d8e93ce

Browse files
feat: an error occurred in the transaction, allow one empty rollback
1 parent 544c6cd commit d8e93ce

File tree

6 files changed

+47
-21
lines changed

6 files changed

+47
-21
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
## v0.7.1
2+
- If an error occurred in the transaction, allow one empty rollback
3+
14
## v0.7.0
25
- Parsed @param then prepared for use with $ prefix (@p -> $p)
36
- Fully integrated with Dapper

src/Ydb.Sdk/src/Ado/YdbCommand.cs

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ protected override DbTransaction? DbTransaction
122122
{
123123
if (value is null or YdbTransaction)
124124
{
125-
_ydbTransaction = (YdbTransaction?)value;
125+
Transaction = (YdbTransaction?)value;
126126
}
127127
else
128128
{
@@ -132,21 +132,7 @@ protected override DbTransaction? DbTransaction
132132
}
133133
}
134134

135-
public new YdbTransaction? Transaction
136-
{
137-
get
138-
{
139-
if (_ydbTransaction?.Completed ?? false)
140-
{
141-
_ydbTransaction = null;
142-
}
143-
144-
return _ydbTransaction;
145-
}
146-
set => _ydbTransaction = value;
147-
}
148-
149-
private YdbTransaction? _ydbTransaction;
135+
public new YdbTransaction? Transaction { get; set; }
150136

151137
public override bool DesignTimeVisible { get; set; }
152138

src/Ydb.Sdk/src/Ado/YdbDataReader.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,7 @@ private void OnFailReadStream()
519519
ReaderState = State.Closed;
520520
if (_ydbTransaction != null)
521521
{
522-
_ydbTransaction.Completed = true;
522+
_ydbTransaction.Failed = true;
523523
}
524524
}
525525

src/Ydb.Sdk/src/Ado/YdbTransaction.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ public sealed class YdbTransaction : DbTransaction
1111

1212
internal string? TxId { get; set; }
1313
internal bool Completed { get; set; }
14+
internal bool Failed { get; set; }
1415

1516
internal TransactionControl TransactionControl => TxId == null
1617
? new TransactionControl { BeginTx = _txMode.TransactionSettings() }
@@ -41,6 +42,14 @@ public override void Rollback()
4142
// TODO propagate cancellation token
4243
public override async Task RollbackAsync(CancellationToken cancellationToken = new())
4344
{
45+
if (Failed)
46+
{
47+
Failed = false;
48+
Completed = true; // make completed
49+
50+
return;
51+
}
52+
4453
await FinishTransaction(txId => DbConnection.Session.RollbackTransaction(txId));
4554
}
4655

@@ -52,7 +61,7 @@ public override void Rollback()
5261

5362
private async Task FinishTransaction(Func<string, Task<Status>> finishMethod)
5463
{
55-
if (Completed || DbConnection.State == ConnectionState.Closed)
64+
if (Failed || Completed || DbConnection.State == ConnectionState.Closed)
5665
{
5766
throw new InvalidOperationException("This YdbTransaction has completed; it is no longer usable");
5867
}

src/Ydb.Sdk/tests/Ado/YdbExceptionTests.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public async Task IsTransient_WhenSchemaError_ReturnFalse()
2121
}
2222

2323
[Fact]
24-
public async Task IsTransient_WhenAborted_ReturnTrue()
24+
public async Task IsTransient_WhenAborted_ReturnTrueAndMakeEmptyRollback()
2525
{
2626
var bankTable = $"Bank_{Utils.Net}";
2727
await using var ydbConnection = new YdbConnection();
@@ -57,5 +57,12 @@ public async Task IsTransient_WhenAborted_ReturnTrue()
5757
{
5858
CommandText = $"DROP TABLE {bankTable}"
5959
}.ExecuteNonQueryAsync();
60+
Assert.Equal("Status: NotFound", Assert.Throws<YdbException>(() => ydbCommand.Transaction.Commit()).Message);
61+
62+
await ydbCommand.Transaction!.RollbackAsync();
63+
Assert.Equal("This YdbTransaction has completed; it is no longer usable",
64+
Assert.Throws<InvalidOperationException>(() => ydbCommand.Transaction!.Commit()).Message);
65+
Assert.Equal("This YdbTransaction has completed; it is no longer usable",
66+
Assert.Throws<InvalidOperationException>(() => ydbCommand.Transaction!.Rollback()).Message);
6067
}
6168
}

src/Ydb.Sdk/tests/Ado/YdbTransactionTests.cs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ public void Commit_WhenEmptyYdbCommand_DoNothing()
9797
}
9898

9999
[Fact]
100-
public void Commit_WhenDoubleCommit_ThrowException()
100+
public void CommitAndRollback_WhenDoubleCommit_ThrowException()
101101
{
102102
using var connection = new YdbConnection();
103103
connection.Open();
@@ -165,7 +165,7 @@ public void CommitAndRollback_WhenConnectionIsClosed_ThrowException()
165165
}
166166

167167
[Fact]
168-
public void Commit_WhenConnectionIsClosedAndTxDoesNotStarted_ThrowException()
168+
public void CommitAndRollback_WhenConnectionIsClosedAndTxDoesNotStarted_ThrowException()
169169
{
170170
using var connection = new YdbConnection();
171171
connection.Open();
@@ -179,6 +179,27 @@ public void Commit_WhenConnectionIsClosedAndTxDoesNotStarted_ThrowException()
179179
Assert.Throws<InvalidOperationException>(() => ydbTransaction.Rollback()).Message);
180180
}
181181

182+
[Fact]
183+
public void CommitAndRollback_WhenTransactionIsFailed_ThrowException()
184+
{
185+
using var connection = new YdbConnection();
186+
connection.Open();
187+
188+
var ydbCommand = connection.CreateCommand();
189+
ydbCommand.Transaction = connection.BeginTransaction();
190+
ydbCommand.Transaction.Failed = true;
191+
ydbCommand.Transaction.TxId = "no_tx";
192+
193+
Assert.Equal("This YdbTransaction has completed; it is no longer usable",
194+
Assert.Throws<InvalidOperationException>(() => ydbCommand.Transaction.Commit()).Message);
195+
196+
ydbCommand.Transaction.Rollback(); // Make completed
197+
Assert.Equal("This YdbTransaction has completed; it is no longer usable",
198+
Assert.Throws<InvalidOperationException>(() => ydbCommand.Transaction.Commit()).Message);
199+
Assert.Equal("This YdbTransaction has completed; it is no longer usable",
200+
Assert.Throws<InvalidOperationException>(() => ydbCommand.Transaction.Rollback()).Message);
201+
}
202+
182203
public async Task InitializeAsync()
183204
{
184205
await using var connection = new YdbConnection();

0 commit comments

Comments
 (0)