Как исправить конфликт с БД 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 и он авт выходит как только выхожу из тела цикла, тогда как лучше решить эту проблему, подскажите пожалуйста.