Как исправить конфликт с БД SQLite(Database is locked)?

В одной кнопке я делаю генерацию подписи при использовании импортированных ключей из БД SQLite. вот код кнопки, который реализует генерацию подписи чисел r и s:

private void Subscribe_Click(object sender, EventArgs e)
{
// Создаем диалоговое окно для выбора файла
OpenFileDialog openFileDialog = new OpenFileDialog();

// Устанавливаем фильтр для выбора только текстовых файлов
openFileDialog.Filter = "Text Files|*.txt";

// Открываем диалоговое окно
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
    // Получаем путь к выбранному файлу
    string filePath = openFileDialog.FileName;

    // Получаем путь к файлу базы данных
    string dbFileName = @"D:\Учеба\ИТИ магис\2 курс 2 сем\Диссертация\проект\Programs\EL_Gamal\EL_Gamal\database\Keys.db";

    // Создаем экземпляр класса ElGamalDigitalSignature
    ElGamalDigitalSignature digitalSignature = new ElGamalDigitalSignature(dbFileName);

    // Создаем экземпляр класса SignatureExporter
    SignatureExporter signatureExporter = new SignatureExporter(dbFileName);

    // Считываем содержимое файла
    string message;
    using (StreamReader reader = new StreamReader(filePath))
    {
        message = reader.ReadToEnd();
    }

    // Подписываем содержимое файла
    byte[] signature = digitalSignature.Sign(message);

    // Разделяем подпись на две части: r и s
    var rBytes = new byte[signature.Length / 2];
    var sBytes = new byte[signature.Length / 2];
    Array.Copy(signature, 0, rBytes, 0, rBytes.Length);
    Array.Copy(signature, rBytes.Length, sBytes, 0, sBytes.Length);

    // Преобразуем r и s в строки для вывода
    string rString = BitConverter.ToString(rBytes).Replace("-", "");
    string sString = BitConverter.ToString(sBytes).Replace("-", "");

    // Выводим результат подписи в MessageBox
    MetroFramework.MetroMessageBox.Show(this, $"Результат подписи:\n r: {rString}\n s: {sString}", "Уведомление");

    // Создаем экземпляр формы Subscribe и передаем значения R и S
    Subscribe subscribeForm = new Subscribe(signatureExporter);
    subscribeForm.SetSignature(rString, sString);
    subscribeForm.Show();
}
}

класс ElGamalDigitalSignature, на который ссылается кнопка:

public class ElGamalDigitalSignature
{
private ElGamalKeyParametersImporter keyImporter;

public ElGamalDigitalSignature(string dbFileName)
{
    keyImporter = new ElGamalKeyParametersImporter(dbFileName);
}

и дальше идет остальной код, но вставил основное с БД. и этот класс ссылается на класс с бд, где и происходит импорт ключей для генерации подписи:

public class ElGamalKeyParametersImporter
{
private string connectionString;

public ElGamalKeyParametersImporter(string dbFileName)
{
    // Формируем строку подключения к базе данных SQLite
    connectionString = $"Data Source={dbFileName};Version=3;";
}
public Tuple<BigInteger, BigInteger> ImportParameters()
{
    try
    {
        using (SQLiteConnection connection = new SQLiteConnection(connectionString))
        {
            connection.Open();
            using (SQLiteCommand command = connection.CreateCommand())
            {
                // Выполняем SQL-запрос для получения параметров из таблицы ElGamalParameters
                command.CommandText = "SELECT P, G FROM ElGamalParameters ORDER BY ID DESC LIMIT 1";
                SQLiteDataReader reader = command.ExecuteReader();
                if (reader.Read())
                {
                    // Преобразуем результаты в значения BigInteger
                    BigInteger p = new BigInteger(reader["P"].ToString());
                    BigInteger g = new BigInteger(reader["G"].ToString());

                    return new Tuple<BigInteger, BigInteger>(p, g);
                }
                else
                {
                    // Если результаты не найдены или произошла ошибка, возвращаем null
                    MetroFramework.MetroMessageBox.Show(null, "Параметры не найдены в базе данных.");
                    return null;
                }

            }
        }
    }

пока только этот метод вставил то есть еще чтоб не показывать весь код класса. и класс, где я хочу экспортировать полученную подись в БД.

public SignatureExporter(string dbFileName)
{
// Формируем строку подключения к базе данных SQLite
connectionString = $"Data Source={dbFileName};Version=3;";
}

public void ExportSignature(byte[] r, byte[] s)
{
try
{
    using (SQLiteConnection connection = new SQLiteConnection(connectionString))
    {
        connection.Open();
        using (SQLiteCommand command = connection.CreateCommand())
        {
            // Подготовка SQL-запроса для вставки значений r и s в таблицу
            command.CommandText = "INSERT INTO Signatures (R, S) VALUES (@r, @s)";
            command.Parameters.AddWithValue("@r", r);
            command.Parameters.AddWithValue("@s", s);

            // Выполнение SQL-запроса
            command.ExecuteNonQuery();
        }
    }
}
catch (Exception ex)
{
    // Обработка ошибок, если они возникнут при экспорте
    MessageBox.Show($"Ошибка при экспорте подписи в базу данных: {ex.Message}");
}
}

и тут я встаю в дилемму с конфликтом обращения к БД, знаю что надо закрыть соединение, хотя я использую тело using и он авт выходит как только выхожу из тела цикла, тогда как лучше решить эту проблему, подскажите пожалуйста.


Ответы (0 шт):