У меня есть база данных SQLite, которая сохраняется в сетевой папке и может быть доступна нескольким пользователям. Теперь необходимо изменить схему этой базы данных (самостоятельно написанной программой), и мне нужно убедиться, что во время операции обновления никто другой не сможет открыть базу данных (ни для записи, ни для чтения).
Насколько мне известно, PRAGMA locking_mode=EXCLUSIVE
может быть использован для блокировки базы данных. К сожалению, эксклюзивная блокировка получается только при выполнении первой операции записи.
Это означает, что во время между открытием базы данных, установкой режима блокировки и первой операцией записи другой пользователь сможет открыть базу данных.
Есть ли способ получить эксклюзивную блокировку при открытии базы данных с System.Data.SQLite из C #?
EDIT Как вы просиликод, здесь вы идете:
void UpdateDatabaseSchema(Boolean UpdateNeeded)
{
// make sure that all SQLite* objects are disposed correctly by using-statement, otherwise database will not be closed correctly!
using (var Connection = new SQLiteConnection("./Database.db"))
using (var Command = Connection.CreateCommand())
{
Connection.Open();
Command.CommandText = "PRAGMA locking_mode=EXCLUSIVE;";
Command.ExecuteNonQuery();
Command.CommandText = "PRAGMA locking_mode;";
using (var DataReader = Command.ExecuteReader())
{
while (DataReader.Read())
{
var Test = DataReader.GetString(0);
}
}
if (UpdateNeeded)
{
if (System.Windows.Forms.MessageBox.Show("Do you want to update the database schema?", "Update needed", System.Windows.Forms.MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes)
{
Command.CommandText = "CREATE TABLE Users (Test TEXT NOT NULL DEFAULT 0);";
Command.ExecuteNonQuery();
}
}
}
}
Очевидно, что чтение режима блокировки доступно только для отладки (и будет удалено для производительного кода).
Теперь, что произойдет, если другой пользователь откроет ту же базу данных? - чуть-чуть - позже, чем первый пользователь, но быстрее нажимает «Да»? Первый пользователь получит сообщение об ошибке, потому что схема уже была изменена.
Да, я мог бы написать утверждение по-другому, но это обновление является лишь примером, в будущем могут быть и будут более сложные запросы, и я не будуне хочу заботиться об этих условиях гонки в каждой команде (по крайней мере, если это возможно).
Следовательно, мне нужно заблокировать базу данных при открытии .
@ C Perkins:
- Решение этой проблемы на основе файловой системы - это то, о чем я не задумывался. Я рассмотрю эту возможность, спасибо за ввод!
- Онлайн-документы также упоминают: «Когда пишется база данных в первый раз,эксклюзивный замок получен и удерживается. "Я знаю, что оно освобождается только при закрытом соединении, проблема только в том, что получено при первой операции записи.