Fixes deadlock issues and concurrent index drop issues

This commit is contained in:
Shannon
2020-04-03 13:54:28 +11:00
parent 60abdd60b5
commit 859546f5a4
3 changed files with 58 additions and 43 deletions

View File

@@ -78,27 +78,29 @@ namespace Umbraco.Tests.Integration.Testing
_schemaPool = new DatabasePool(_localDb, _instance, DatabaseName + "-Schema", tempName, _filesPath, schemaSize, schemaParallel, delete: true, prepare: RebuildSchema);
}
public void AttachEmpty()
public int AttachEmpty()
{
if (_emptyPool == null)
Create();
_currentCstr = _emptyPool.AttachDatabase();
_currentCstr = _emptyPool.AttachDatabase(out var id);
_currentPool = _emptyPool;
return id;
}
public void AttachSchema()
public int AttachSchema()
{
if (_schemaPool == null)
Create();
_currentCstr = _schemaPool.AttachDatabase();
_currentCstr = _schemaPool.AttachDatabase(out var id);
_currentPool = _schemaPool;
return id;
}
public void Detach()
public void Detach(int id)
{
_currentPool.DetachDatabase();
_currentPool.DetachDatabase(id);
}
private void RebuildSchema(DbConnection conn, IDbCommand cmd)
@@ -188,7 +190,25 @@ namespace Umbraco.Tests.Integration.Testing
from sys.tables;
exec sp_executesql @stmt;
";
cmd.ExecuteNonQuery();
// rudimentary retry policy since a db can still be in use when we try to drop
for (var i = 0; i < 5; i++)
{
try
{
cmd.ExecuteNonQuery();
return;
}
catch (SqlException ex)
{
// This can occur when there's a transaction deadlock which means (i think) that the database is still in use and hasn't been closed properly yet
// so we need to just wait a little bit
Thread.Sleep(1000);
if (i == 4)
throw;
}
}
}
public static void KillLocalDb()
@@ -266,22 +286,19 @@ namespace Umbraco.Tests.Integration.Testing
}
}
public string AttachDatabase()
public string AttachDatabase(out int id)
{
try
{
_current = _readyQueue.Take();
}
catch (InvalidOperationException)
{
_current = 0;
return null;
}
_current = _readyQueue.Take();
id = _current;
return ConnectionString(_current);
}
public void DetachDatabase()
public void DetachDatabase(int id)
{
if (id != _current)
throw new InvalidOperationException("Cannot detatch the non-current db");
_prepareQueue.Add(_current);
}