Я запускаю 5 приложений, использующих одну и ту же базу данных sqlite
(каждое приложение - это отдельный процесс). К сожалению, такие операции, как GetEmptyPort
, должны быть атомарными, чтобы предотвратить возврат одинаковых значений. Прямо сейчас я добиваюсь этого, используя систему Mutex
, но мне не нравится это решение. Есть ли какое-либо встроенное решение для этого в чистом виде sqlite
?
Это мой код:
private static Mutex DB_MUTEX = new Mutex(false, "FOO_DB_MUTEX");
private T OnMutexWork<T>(Func<T> func)
{
try
{
DB_MUTEX.WaitOne();
return func.Invoke();
}
catch (Exception ex)
{
throw;
}
finally
{
DB_MUTEX.ReleaseMutex();
}
}
private SQLiteConnection GetConnection()
{
return new SQLiteConnection(databasePath);
}
private int GetEmptyPort(int min, int max)
{
return OnMutexWork<int>(() =>
{
using (var conn = GetConnection())
{
var allPorts = conn.Table<Port>()
.ToList();
for (int i = min; i <= max; i++)
{
if (!allPorts.Any(x => x.Value == i))
{
var item = new Port() { Value = i};
conn.Insert(item);
return i;
}
}
throw new Exception("Couldn't find empty port");
}
});
}
Я попробовал то, что @Shawn предложил:
private int GetEmptyPort(int min, int max)
{
using (var conn = GetConnection())
{
conn.RunInTransaction(() =>
{
var allPorts = conn.Table<Port>()
.ToList();
for (int i = min; i <= max; i++)
{
if (!allPorts.Any(x => x.Value == i))
{
var item = new Port() { Value = i};
conn.Insert(item);
return i;
}
}
});
throw new Exception("Couldn't find empty port");
}
}
Но я получаю SQLite.SQLiteException: 'Busy'
ошибку при доступе к базе данных из разных соединений.