Как бороться с ошибками sqlite? - PullRequest
2 голосов
/ 16 мая 2010

У меня есть долго работающее приложение, написанное на смеси C и C ++, которое хранит данные в sqlite.

Хотя я уверен, что зафиксированные данные останутся доступными (за исключением механического сбоя), а непереданные данные не будут, мне не ясно, что я могу сделать с такого рода средним состоянием.

Я делаю большое количество вставок в транзакции и затем фиксирую ее. Когда в данном утверждении возникает ошибка, я могу запланировать ее попытку в какой-то момент в будущем. Похоже, что некоторые ошибки могут неявно откатить мою транзакцию (что было бы нежелательно, если истина).

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

Каков рекомендуемый механизм обработки ошибок в такой ситуации?

Ответы [ 4 ]

1 голос
/ 17 мая 2010

В COMMIT, если вы видите ошибку SQLITE_BUSY, вы должны повторить попытку КОМИТ. Это может сработать. Еще лучше установить обратный вызов занятого обработчика для обработки SQLITE_BUSY.

Другая причина сбоя COMMIT - это отложенный внешний ключ. нарушение. Если это произойдет, вы можете исправить нарушение FK и затем COMMIT. Трудно увидеть, что это делает беспилотное приложение.

Другие ошибки, которые вы, вероятно, должны просто оставить и ОТКРЫТЬ сделка.

Если возникает ошибка ввода-вывода или OOM, текущая транзакция может быть откат. Это связано с тем, что некоторые ошибки ввода / вывода покидают SQLite не уверены, совпадают ли его внутренние структуры данных что на самом деле на диске. Если бы мы продолжили в этой точке база данных может быть повреждена.

Вы можете проверить, был или нет откат транзакции SQLite с использованием API sqlite3_get_autocommit ().

Если во время COMMIT возникает ошибка ввода-вывода или OOM, транзакция может все еще были совершены. Это может произойти, например, если пользователь вырывает карту памяти из камеры так же, как сделка совершена. Это вообще невозможно узнать если данные попали на постоянный носитель без чтения БД и проверка на уровне приложения.

0 голосов
/ 16 мая 2010

Базы данных разработаны в явном виде, так что данные всегда либо фиксируются, либо не передаются. Когда данные фиксируются, они не теряются произвольно, потому что находятся в постоянном хранилище (ну, в файле на диске, что является хорошим приближением). Если вы выполняете ручное управление транзакциями (похоже на это), то база данных не будет или COMMIT или ROLLBACK, пока вас не попросят. Ошибки в утверждениях можно устранить, не потеряв ничего, что уже сделано.

Если вы находитесь в состоянии, когда вы не можете использовать COMMIT или ROLLBACK, то у вас большие проблемы. Если это потому, что вам не хватает памяти или дискового пространства (или квоты), значит, вы неправильно подготовили приложение, и вам следует сначала это исправить.

Вы также можете подумать об ограничении длины транзакций, чтобы она была менее катастрофической (с точки зрения работы по восстановлению) при возникновении некоторого сбоя.

0 голосов
/ 16 мая 2010

Хотя я не согласен с более ранними ответами в том, что SQLite наиболее определенно может испытывать временные ошибки, которые позволят вам успешно выполнить COMMIT, просто повторив попытку несколько раз, у них есть хорошая точка зрения, что это не относится ко всем ошибкам. Не забудьте установить пределы повторов и, возможно, также проверить причину сбоя, а не слепо повторять навсегда.

0 голосов
/ 16 мая 2010

Вставка нулевого значения в столбец без значения NULL вряд ли удастся, независимо от того, сколько раз вы пытаетесь.

Нет единого решения вашей проблемы. Например, если вы нарушаете ограничения базы данных, вы должны изменить свои данные, прежде чем делать еще одну попытку. Если у вас нет памяти / свободного места на диске - освободите немного и повторите попытку.

Полагаю, вам нужно больше узнать о транзакциях и свойствах ACID.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...