Also habe ich zwei Klassen, jede besteht aus Datenbank-Integrationstests. In jedem Konstruktor Klassen ich eine Methode setzte die Datenbank zurück:Deadlock auf xUnit Test bei der Verarbeitung von Daten auf der Datenbank
public class FirstClassSpec {
public FirstClassSpec() {
var dataSetup = new DataSetup();
dataSetup.CleanTables();
}
[Fact]
public async Task FirstTest() {
using(var conn = new SqlConnection("connStringHere")){
var result = await conn.ExecuteAsync("someSqlCommand");
Assert.True(result > 0);
}
}
}
public class SecondClassSpec {
public SecondClassSpec() {
var dataSetup = new DataSetup();
dataSetup.CleanTables();
}
[Fact]
public async Task SecondTest() {
using(var conn = new SqlConnection("connStringHere")){
var result = await conn.ExecuteAsync("someSqlCommand");
Assert.True(result > 0);
}
}
}
public class DataSetup {
public void CleanTables() {
using(var conn = new SqlConnection("connStringHere")){
await conn.Execute("someSqlCommandToCleanTables");
}
}
}
Um die Tests von Visual Studio 2015 zu laufen, ich benutze Run All Tests
in Test Explorer
. Ich habe die Nachricht von
Transaktion (Prozess-ID {someID}) wurde auf Sperre Ressourcen Deadlock mit einem anderen Prozess
Dieses Problem tritt nur, wenn ich alle Tests laufen. Wenn ich jeden Test einzeln oder mit mehreren Tests, aber aus derselben Klasse, ausfühle, tritt der Deadlock nicht auf. Ich fand heraus, dass die CleanTables()
Methode, die im Konstruktor der Klassen aufgerufen wird, dies verursacht. Ich nehme an, die Tests laufen parallel, und CleanTables()
wurde gleichzeitig von den beiden Klassen aufgerufen. So dann habe ich versucht CleanTables()
in eine Asynchron-Methode zu machen:
public async Task<int> CleanTables() {
using(var conn = new SqlConnection("connStringHere")){
return await conn.Execute("someSqlCommandToCleanTables");
}
}
und dann auf den Klassen-Konstruktor ich es so nennen:
Aber jetzt, wenn ich zu Run All Tests
versuchen, die Tests Sie liefen, aber sie werden nie fertig und ich bekomme nie das Ergebnis.
Meine Frage ist, warum der Deadlock auftritt? und warum wurde die CleanTables()
-Methode in async geändert, damit die laufenden Tests nie ausgeführt werden? Ich muss wirklich die Tabellen vor jedem Testlauf säubern.
----------------- UPDATE -----------------------
ich habe versucht, alle Testklassen dekoriert mit [Collection["CollectionName"]]
, mit jeder Klasse hat verschiedene Namen:
[Collection["FirstSpec"]]
public class FirstClassSpec {
//....
}
[Collection["SecondSpec"]]
public class FirstClassSpec {
//....
}
Aber die Deadlock auftritt ..
---------- ------- UPDATE 2 -----------------------
Stellt fest, dass Klassen, die den gleichen Auflistungsnamen aufweisen, sequenziell ausgeführt werden und dadurch das Deadlock-Problem gelöst wird.
Haben Sie versucht, mit Hilfe von [SQL Server Profiler, um die Analyse der Sackgasse] (https://docs.microsoft.com/ de-de/sql/tools/sql-server-profiler/analysieren-deadlocks-with-sql-server-profiler)? Es hat mir in der Vergangenheit geholfen. –