Skip to content

Commit a3e0f54

Browse files
committed
Failing test for transaction abortion handling (#301)
1 parent cef356d commit a3e0f54

File tree

1 file changed

+39
-1
lines changed

1 file changed

+39
-1
lines changed

DuckDB.NET.Test/TransactionTests.cs

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,4 +113,42 @@ public void TransactionInvalidStateTest()
113113
Connection.Invoking(connection => connection.BeginTransaction(IsolationLevel.Serializable)).Should()
114114
.Throw<ArgumentException>();
115115
}
116-
}
116+
117+
[Fact]
118+
public void AbortedTransactionTest()
119+
{
120+
// This block of code is to make the transaction commit fail using an index limitation in duckdb
121+
// (https://github.com/duckdb/duckdb/issues/17802)
122+
Command.CommandText = "CREATE TABLE IF NOT EXISTS test_table (id INTEGER PRIMARY KEY);";
123+
Command.ExecuteNonQuery();
124+
Command.CommandText = "INSERT OR IGNORE INTO test_table VALUES (1);";
125+
Command.ExecuteNonQuery();
126+
// Keep a reference to the row in an open transaction to trigger the concurrent access limitation
127+
using var tx1 = Connection.BeginTransaction();
128+
Command.Transaction = tx1;
129+
Command.CommandText = "SELECT id FROM test_table LIMIT 1;";
130+
using var reader1 = Command.ExecuteReader();
131+
using var conn2 = Connection.Duplicate();
132+
conn2.Open();
133+
using var cmd2 = conn2.CreateCommand();
134+
cmd2.CommandText = "UPDATE test_table SET id = 1 WHERE id = 1;";
135+
cmd2.ExecuteNonQuery();
136+
var tx2 = conn2.BeginTransaction();
137+
cmd2.Transaction = tx2;
138+
cmd2.CommandText = "UPDATE test_table SET id = 1 WHERE id = 1;";
139+
cmd2.ExecuteNonQuery();
140+
141+
using (new FluentAssertions.Execution.AssertionScope())
142+
{
143+
// Check that when the transaction commit fails and the transaction
144+
// enters an aborted state, the transaction and connection objects
145+
// remain in the expected state.
146+
tx2.Invoking(tx2 => tx2.Commit()).Should().Throw<DuckDBException>().Where(ex => ex.ErrorType == Native.DuckDBErrorType.Transaction);
147+
tx2.Invoking(tx2 => tx2.Commit()).Should().Throw<InvalidOperationException>();
148+
tx2.Invoking(tx2 => tx2.Rollback()).Should().Throw<InvalidOperationException>();
149+
tx2.Invoking(tx2 => tx2.Dispose()).Should().NotThrow();
150+
151+
conn2.Invoking(conn2 => conn2.BeginTransaction()).Should().NotThrow();
152+
}
153+
}
154+
}

0 commit comments

Comments
 (0)