I used this trick for Integration tests to ensures that each test is ran in a transaction and this transaction is rolled back:
I defined following base class and all my integration test classes can inherit from it.
public abstract class IntegrationTestBase
{
private TransactionScope scope;
[TestInitialize]
public void TestInitialize()
{
scope = new TransactionScope();
}
[TestCleanup]
public void TestCleanup()
{
scope.Dispose();
}
}
It works but not for following code:
[TestMethod]
public void SaveTwoDocumentsSimultaneously_WorkSuccessfully()
{
//Assign
var doc1 = new Document() { Number = "Test-1" };
var doc2 = new Document() { Number = "Test-2" };
//Action
Parallel.Invoke(() => SaveNewDocument(doc1), () => SaveNewDocument(doc2));
//Assert
Assert.IsTrue(true);
}
void SaveNewDocument(Document doc)
{
using (var ctx = new MyDbContext())
{
ctx.Documents.Add(doc);
ctx.SaveChanges();
}
}
When the test is passed, there is a record number Test-2 in the database, in other words, the transaction has not been rolled back as I expect(I expect There is no record with numbers Test-1 and Test-2 in the database).
I think I should use DependentTransaction
according this link.
How can I use the Transaction
that opened in IntegrationTestBase
(using TransactionScope
) and to use it as parent Transaction?
6
You simply can’t use concurrency using one connection to DB. A single connection works synchronously, and if you try to make queries in parallel using one connection, that would lead to unpredictable behavior. Instead, if u want to query DB in parallel, create different connections and use them concurrently.
Bottom-line: one connection allows one query at a time.
PS and due to the fact that u can query DB only synchronously using one connection, you surely can’t use concurrency within a single transaction, because single transaction belongs to single connection
Андрей Ковтун is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
1