powered by simpleCommunicator - 2.0.27     © 2024 Programmizd 02
Map
Форумы / SQLite [игнор отключен] [закрыт для гостей] / database is locked database is locked - при вставке большого к-во записей
20 сообщений из 20, страница 1 из 1
database is locked database is locked - при вставке большого к-во записей
    #39851212
Фотография potkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый День!
Использую: System.Data.SQLite 1.0.111.0 (3.28.0) + Транзакции
При вставке большого к-ва записей (350 в одну таблицу и 2 000 записей в другую) получаю исключение:
database is locked database is locked
При маленьком к-ве вставок - всё "ок".

Памяти 4 Гига. Вроде хватает.
На быстром ПК все отрабатывает, а на Сервера под нагрузкой - нет, но иногда бывает отработает, если нет нагрузки на Сервере.
Ну и пробовал баловаться с таймоутами, например так:
cmd.CommandTimeout = 100000;
не помогает

Подскажите, есть ли решение данной проблемы?
...
Рейтинг: 0 / 0
database is locked database is locked - при вставке большого к-во записей
    #39851267
Фотография VSVLAD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
potkin,

Вставка происходит в одном потоке или несколько потоков/процессов пишут одновременно?
...
Рейтинг: 0 / 0
database is locked database is locked - при вставке большого к-во записей
    #39851269
Фотография VSVLAD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VSVLAD,

ну и ещё после вставки, закрывается ли корректно подключение? чистятся ресурсы (Dispose)?
...
Рейтинг: 0 / 0
database is locked database is locked - при вставке большого к-во записей
    #39851352
Фотография potkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторВставка происходит в одном потоке или несколько потоков/процессов пишут одновременно?
В одном потоке, конечно.
В контексте одной транзакции.
Я думаю тут вопрос с таймаутом, он вроде 30 секунд. Возможно при нагрузке этого мало.
Сохранения происходят в цикле for . Таких циклов 2 000 , на ~ 1 000 вылет с ошибкой.

авторну и ещё после вставки, закрывается ли корректно подключение? чистятся ресурсы (Dispose)?
Да, конечно.
Код: c#
1.
2.
3.
4.
5.
using(SQLiteConnection con = ...)
{
   //...
   con.Close(); con.Dispose(); //это не нужно, но я всё равно делаю.
}


Запускаю на отдельном аккаунте, где работаю я один, если загрузка Сервера и операция длится более 30 секунд - ошибка .

Я думаю вопрос таки в ТаймАуте, но как его увеличить?
Что я ни делал, все равно 30 секунд и ни секундой более! (((
...
Рейтинг: 0 / 0
database is locked database is locked - при вставке большого к-во записей
    #39851406
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
potkinавторВставка происходит в одном потоке или несколько потоков/процессов пишут одновременно?
В одном потоке, конечно.
В контексте одной транзакции.
В одной транзакции не может быть такого в принципе. Эта ошибка возникает когда одно соединение открыло транзакцию и что-то делает, а в это время второе пытается начать транзакцию, но долго не может, в итоге вываливается с ошибкой.
Т.е. получается у тебя несколько соединений с БД, если такого быть не должно - разбирайся откуда они.

potkinЯ думаю тут вопрос с таймаутом, он вроде 30 секунд. Возможно при нагрузке этого мало.
Сохранения происходят в цикле for . Таких циклов 2 000 , на ~ 1 000 вылет с ошибкой.
Сделай обработку этой ошибки: когда произойдет - запускай слетевший цикл повторно.

Попробуй поиграть настройкой PRAGMA busy_timeout

PS Если заполнение БД не критично к сбоям, например база заполняется с нуля и умершую базу можно создать повторно, то можно ускорить этими настройками
Код: sql
1.
2.
3.
pragma synhronous=OFF;
pragma journal_mode=OFF;
pragma cache_size=-32678;
...
Рейтинг: 0 / 0
database is locked database is locked - при вставке большого к-во записей
    #39852782
Фотография potkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторВ одной транзакции не может быть такого в принципе. Эта ошибка возникает когда одно соединение открыло транзакцию и что-то делает, а в это время второе пытается начать транзакцию, но долго не может, в итоге вываливается с ошибкой.
Т.е. получается у тебя несколько соединений с БД, если такого быть не должно - разбирайся откуда они.

Проект писал я.
Запуская локально на "слабой" машине.
Транзакция только одна. Даже отдельный проект создал, там всего одна функция на запись в БД. Все тесты локально.
Вылетает ошибка, если запись в Базу длится более 30 секунд.
Если машина "сильная", то всё пишется (запись проходит быстрее 30 секунд).
Думал, что ошибка в провайдере "System.Data.SQLite", но у меня есть проект на Qt (Win, Lnux, ...), там такая же хреня ((((
Вся проблема в ТаймАуте!
авторСделай обработку этой ошибки: когда произойдет - запускай слетевший цикл повторно.
Опять ошибка вылетит, нужно время, вопрос как его увеличить более 30 секунд ...
авторPRAGMA busy_timeout
Уже перепробовал всё, что советовал гугл, пока что ничего не помогает.
Открываю соединение, запускаю команду: "PRAGMA busy_timeout=500000;" или такую "PRAGMA busy_timeout;".
Запускаю транзакцию.
Через 30 секунд - ошибка.
авторPS Если заполнение БД не критично к сбоям, например база заполняется с нуля и умершую базу можно создать повторно, то можно ускорить этими настройками

Критично.

Вопрос открыт: Как увеличить ТаймАут работы Транзакции?
...
Рейтинг: 0 / 0
database is locked database is locked - при вставке большого к-во записей
    #39852790
Фотография potkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кстати:
Код: c#
1.
2.
3.
4.
using (SQLiteConnection con = new SQLiteConnection("Data Source='d:\base.db';New=False;Version=3;foreign keys=true;Connection Timeout=10000000;Timeout=10000000;"))
{
   con.Open();
}


параметры имеют такие значения:
con.BusyTimeout = 0
con.ConnectionTimeout = 15
con.DefaultTimeout = 30
con.WaitTimeout = 30000
...
Рейтинг: 0 / 0
database is locked database is locked - при вставке большого к-во записей
    #39852961
Фотография VSVLAD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Создал тестовый проект
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
Imports System.Data.SQLite

Module Module1

    Sub Main()

        Using con As New SQLiteConnection("Data Source='d:\base.db';foreign keys=true")

            con.Open()
            Dim cmd = con.CreateCommand()

            cmd.CommandText = "select sqlite_version()"
            Console.WriteLine($"SQLite version: {cmd.ExecuteScalar()}")
            Console.WriteLine($"CommandTimeout = {cmd.CommandTimeout}")
            Console.WriteLine($"ConnectionTimeout = {con.ConnectionTimeout}")
            Console.WriteLine($"BusyTimeout = {con.BusyTimeout}")

            cmd.CommandText = "create table if not exists t1(num Integer, ondate datetime)"
            cmd.ExecuteNonQuery()

            Console.WriteLine("Открываем транзакцию")
            cmd.CommandText = "begin transaction"
            cmd.ExecuteNonQuery()

            cmd.CommandText = "insert into t1 values(@num, @ondate)"
            cmd.Parameters.Add("@num", DbType.Int32)
            cmd.Parameters.Add("@ondate", DbType.DateTime)

            For I = 1 To 600
                cmd.Parameters.Item("@num").Value = I
                cmd.Parameters.Item("@ondate").Value = Now()
                cmd.ExecuteNonQuery()

                Console.WriteLine($"Добавили запись #{I} и ждём 1 секунду")
                Threading.Thread.Sleep(1000)
            Next

            cmd.CommandText = "commit"
            cmd.ExecuteNonQuery()
        End Using
    End Sub

End Module



Запускаю. На 120 секунде устал смотреть, всё работает. Транзакция открыта и в неё пишется. Журнал транзакций растёт. PRAGMA busy_timeout стоит по умолчанию и равна 3000 мс. Настройки таймаута соединения и команды не трогаю. Также для успокоения совести нагуглил на стековерфлоу, что размер транзакции в SQLite не ограничен.

Отсюда вопрос: скорее всего или ваш провайдер старый или SQLite или ваш код имеет какие-то нюансы, поэтому нужен от вас минимальный проект, который даёт сбой.

Проверял на конфигурации:
Код: sql
1.
2.
3.
4.
5.
Пакет из Nuget System.Data.SQLite: 1.0.111.0
SQLite version: 3.28.0
CommandTimeout = 30
ConnectionTimeout = 15
BusyTimeout = 0
...
Рейтинг: 0 / 0
database is locked database is locked - при вставке большого к-во записей
    #39852993
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VSVLADСоздал тестовый проект
Тоже хотел так сделать, но ты опередил. Просьба к ТС повторить запуск этого кода, если работает, то приближать код к реальному до тех пор пока глюк не повторится.
ИМХО обычно при построении модели проблемы приходит решение как проблему обойти.
...
Рейтинг: 0 / 0
database is locked database is locked - при вставке большого к-во записей
    #39853492
Фотография potkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Проблема была таки в чтении.
При записи данных, некоторые данные получались из той самой БД (из справочника).
1) Запускалась Транзакция
2) В цикле:
2.1) Читались некоторые данные - вот тут на шаге 426 (ровно 426) получал исключение о блокировки базы.
2.2) Писались в БД

При том все вариации Прагмы не помогают:
Код: sql
1.
PRAGMA locking_mode=ХХХ;



Решил:
До Транзакции читаю данные в массив и потом их подставляю в Инзерт.
...
Рейтинг: 0 / 0
database is locked database is locked - при вставке большого к-во записей
    #39853493
Фотография potkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
При том пробовал в одном соединении читать данные из справочника и писать
Пробовал создавал 2-а соединения: одним читаю, другим пишу + разные вариации ПРАГМы. Ошибка (
...
Рейтинг: 0 / 0
database is locked database is locked - при вставке большого к-во записей
    #39853499
Фотография VSVLAD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
potkinПри том пробовал в одном соединении читать данные из справочника и писать
SQLite проектировался, чтобы было много читателей и один писатель. Блокировка происходит на уровне блокировки файла, поэтому не важно в двух соединениях происходит или даже в двух разных приложениях.

Если необходимо часто читать и одновременно дописывать, то можно попробовать включить режим журналирования WAL. Подробнее в официальной доке почитайте. В вашем проекте это может быть решением
...
Рейтинг: 0 / 0
database is locked database is locked - при вставке большого к-во записей
    #39853656
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
potkinПроблема была таки в чтении.
При записи данных, некоторые данные получались из той самой БД (из справочника).
1) Запускалась Транзакция
2) В цикле:
2.1) Читались некоторые данные - вот тут на шаге 426 (ровно 426) получал исключение о блокировки базы.
2.2) Писались в БД

При том все вариации Прагмы не помогают:
Код: sql
1.
PRAGMA locking_mode=ХХХ;


Ты дэдлок устроил. Сначала запись идет в кэш, в это время стоит блокировка разрешающая чтение, но по заполнению кэша блокировка меняется на монопольную (запрещающую чтение) и начинается запись непосредственно в базу, тут при попытке чтения повисает. Т.е. надо увеличивать размер кэша
Код: sql
1.
pragma cache_size=...;



Еще можно попробовать разрешить грязное чтение, но тут я не уверен что это стоит делать
Код: sql
1.
pragma read_uncommitted=ON;


potkinРешил:
До Транзакции читаю данные в массив и потом их подставляю в Инзерт.
И правильно. Так будет лучше всего.
...
Рейтинг: 0 / 0
database is locked database is locked - при вставке большого к-во записей
    #39874950
YUBA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T, не может быть такого, по 30 тыс строк пишу в одной транзакции до commit, и кеш вообще не трогал - по умолчанию. Никаких проблем. Версия 3.29.
М.б. версия древняя у товарища?
...
Рейтинг: 0 / 0
database is locked database is locked - при вставке большого к-во записей
    #39874951
YUBA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T, имхо, согласно докам кеш автоматом увеличивается и моноблокировка происходит только по commit.
...
Рейтинг: 0 / 0
database is locked database is locked - при вставке большого к-во записей
    #39874986
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YUBADima T, не может быть такого, по 30 тыс строк пишу в одной транзакции до commit, и кеш вообще не трогал - по умолчанию. Никаких проблем. Версия 3.29.
М.б. версия древняя у товарища?
Топик пробовал почитать? 21956985
...
Рейтинг: 0 / 0
database is locked database is locked - при вставке большого к-во записей
    #39875078
YUBA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T, пробовал. Не знаю, откуда у него такое.
А вот ты ерунду написал.)) Про кеш. Доки пробовал читать по Sqlite?
...
Рейтинг: 0 / 0
database is locked database is locked - при вставке большого к-во записей
    #39875113
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YUBADima T, пробовал. Не знаю, откуда у него такое.
А вот ты ерунду написал.)) Про кеш. Доки пробовал читать по Sqlite?
Пробовал, даже в переводе книги участвовал 21709672
Если ты что-то считаешь неверным - будь добр сам дать ссылку на документацию.
...
Рейтинг: 0 / 0
database is locked database is locked - при вставке большого к-во записей
    #39875177
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нашел в книге 21709672
6.4.1 Переход в Состояние EXCLUSIVEКогда конкретно менеджер страниц меняет состояние RESERVED на EXCLUSIVE и почему?
...
Первому заполнению кэша страниц соответствует мягкий предел. В этот момент кэш хранит смесь из неизмененных и измененных страниц. Менеджер страниц пытается очистить кэш. Он проходит по кэшу, избавляясь от неизмененных страниц. После очистки менеджер продолжать работу с освобожденной памятью до тех пор, пока кэш не заполнится снова. Далее, если есть хоть одна неизмененная страница, можно повторить процесс очистки от них. Это означает появление жесткого предела. В этот момент менеджер
страниц не имеет другой возможности, кроме как переходить к состоянию EXCLUSIVE.

С другой стороны, прагма cach_size, проявляется в состоянии RESERVED. Как объяснялось в секции 5.4.3 , прагма управляет размером кэша страниц. Чем больше кэш, тем больше измененных страниц в нем может запомнить менеджер страниц и тем больше работы соединение может выполнить, не меняя свое состояние на EXCLUSIVE.
...
...
Рейтинг: 0 / 0
database is locked database is locked - при вставке большого к-во записей
    #39875240
YUBA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,
Код: plaintext
1.
Рекомендуемый размер кэша по умолчанию - -2000, что означает, что размер кэша ограничен 2048000 байтами памяти.

Если это не блобы, то уже этого размера на 2600 строк уже выше крыши.
...
Рейтинг: 0 / 0
20 сообщений из 20, страница 1 из 1
Форумы / SQLite [игнор отключен] [закрыт для гостей] / database is locked database is locked - при вставке большого к-во записей
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали тему (0):
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]