Я выполняю большое количество INSERTS в базе данных SQLite. Я использую только один поток. Я загружаю записи для повышения производительности и немного защиты в случае сбоя. В основном я кэширую кучу данных в памяти, а затем, когда я считаю нужным, я просматриваю все эти данные и выполняю INSERTS. Код для этого показан ниже:
    public void Commit()
    {
        using (SQLiteConnection conn = new SQLiteConnection(this.connString))
        {
            conn.Open();
            using (SQLiteTransaction trans = conn.BeginTransaction())
            {
                using (SQLiteCommand command = conn.CreateCommand())
                {
                    command.CommandText = "INSERT OR IGNORE INTO [MY_TABLE] (col1, col2) VALUES (?,?)";
                    command.Parameters.Add(this.col1Param);
                    command.Parameters.Add(this.col2Param);
                    foreach (Data o in this.dataTemp)
                    {
                        this.col1Param.Value = o.Col1Prop;
                        this. col2Param.Value = o.Col2Prop;
                        command.ExecuteNonQuery();
                    }
                }
                this.TryHandleCommit(trans);
            }
            conn.Close();
        }
    }
Теперь я использую следующий трюк, чтобы заставить вещь в конечном итоге работать:
    private void TryHandleCommit(SQLiteTransaction trans)
    {
        try
        {
            trans.Commit();
        }
        catch (Exception e)
        {
            Console.WriteLine("Trying again...");
            this.TryHandleCommit(trans);
        }
    }
Я создаю свою БД следующим образом:
    public DataBase(String path)
    {
        //build connection string
        SQLiteConnectionStringBuilder connString = new SQLiteConnectionStringBuilder();
        connString.DataSource = path;
        connString.Version = 3;
        connString.DefaultTimeout = 5;
        connString.JournalMode = SQLiteJournalModeEnum.Persist;
        connString.UseUTF16Encoding = true;
        using (connection = new SQLiteConnection(connString.ToString()))
        {
            //check for existence of db
            FileInfo f = new FileInfo(path);
            if (!f.Exists)  //build new blank db
            {
                SQLiteConnection.CreateFile(path);
                connection.Open();
                using (SQLiteTransaction trans = connection.BeginTransaction())
                {
                    using (SQLiteCommand command = connection.CreateCommand())
                    {
                        command.CommandText = DataBase.CREATE_MATCHES;
                        command.ExecuteNonQuery();
                        command.CommandText = DataBase.CREATE_STRING_DATA;
                        command.ExecuteNonQuery();
                        //TODO add logging
                    }
                    trans.Commit();
                }
                connection.Close();
            }
        }            
    }
Затем я экспортирую строку подключения и использую ее для получения новых подключений в разных частях программы.
По-видимому, случайные интервалы, хотя и слишком велики, чтобы игнорировать или иным образом обходить эту проблему, я получаю необработанное SQLiteException: файл базы данных заблокирован. Это происходит, когда я пытаюсь совершить транзакцию. Кажется, что ошибки до этого не возникли. Это не всегда. Иногда все работает без заминки.
- Чтение не выполняется над этими файлами до завершения коммитов.
- У меня есть самый последний SQLite файл.
- Я компилирую для .NET 2.0.
- Я использую VS 2008.
- db - локальный файл.
- Все это действие инкапсулируется в один поток/процесс.
- Защита от вирусов отключена (хотя я думаю, что это было актуально только в том случае, если вы подключались по сети?).
- По сообщению Scotsman я внедрил следующие изменения:
- Режим журнала установлен на "Постоянно"
-  Файлы DB, хранящиеся в C:\Docs + Settings\ApplicationData через System.Windows.Forms.Application.AppDataвызов Windows
- Внутреннее исключение
- Проверено на двух разных машинах (хотя очень похожее аппаратное и программное обеспечение)
- Был запущен Process Monitor - никакие посторонние процессы не привязаны к файлам DB - проблема определенно в моем коде...
Кто-нибудь знает, что происходит здесь?
Я знаю, что я просто сбросил весь беспорядок кода, но я пытался понять это слишком долго. Спасибо всем, кто дойдет до конца этого вопроса!
Брайен
ОБНОВЛЕНИЕ:
Спасибо за предложения! Я реализовал многие из предлагаемых изменений. Я чувствую, что мы приближаемся к ответу... однако...
Приведенный выше технический код работает, однако он не детерминирован! Не гарантируется что-либо сделать, кроме спина в нейтральной навсегда. На практике это работает где-то между 1-й и 10-й итерациями. Если я улажу свои коммиты с разумным интервалом, урон будет уменьшен, но я действительно не хочу оставлять вещи в этом состоянии...
Дополнительные предложения приветствуются!
