Я разработал приложения в flex. Одно приложение постоянно извлекает данные из Интернета, а другое можно открывать и закрывать, когда вы хотите, оба приложения используют одну и ту же базу данных. Проблема в том, что наугад я получаю Error #3119: Database file is currently locked
. Разве нельзя иметь два стабильных соединения в среде Adobe AIR? У кого-нибудь есть решения?
Ошибка № 3119: файл базы данных в настоящее время заблокирован
Ответы (3)
Думаю, нет. Не сразу.
Я знаю, что это действительно старый вопрос, но я сам столкнулся с этой проблемой и нашел решение для тех, кто может столкнуться с этим. Я надеюсь, что это кому-то поможет, потому что я знаю, что все, что я мог найти по этой теме, было ложной информацией, подобной той, которую дал Конрад. На самом деле вы можете иметь несколько открытых подключений к базе данных. На самом деле, в моем приложении у меня есть асинхронное соединение, используемое для записи данных в базу данных (INSERT, UPDATE, DELETE), и синхронное соединение только для чтения для чтения из базы данных. В асинхронном соединении для каждого выполнения я всегда получаю немедленную блокировку, помещая все операторы в транзакцию, используя
conn.begin(SQLTransactionLockType.IMMEDIATE);
Это позволит вам читать из базы данных во время записи в нее с помощью другого соединения. Я столкнулся с проблемой при попытке чтения из базы данных из одного соединения после фиксации этого асинхронного оператора и до того, как он фактически закончил запись данных. Таким образом, несмотря на то, что в документации для SQLTransactionLockType.IMMEDIATE
указано, что вы все еще можете выполнять чтение, пока он заблокирован, вы на самом деле не можете, пока другой оператор активно записывает данные.
Я обошел это, написав собственное выполнение для синхронного соединения. Он просто пытается выполниться, и если это не удается из-за ошибки № 3119, попробуйте еще раз, пока не добьетесь успеха. Между каждым вызовом функции данные будут продолжать записываться в базу данных и в конечном итоге перестанут быть занятыми. Вот код этой функции:
public static function execute(stmt:SQLStatement):void {
try {
stmt.execute();
} catch (e:SQLError) {
if(e.errorID == 3119) {
execute(stmt);
} else {
trace(e.details + "\n" + e.getStackTrace());
if(stmt.sqlConnection != null && stmt.sqlConnection.inTransaction) {
stmt.sqlConnection.rollback();
}
}
}
}
Еще одна хитрость, на которую следует обратить внимание при возникновении этой ошибки (если вы все равно такой же идиот, как я), — это проверить, открыт ли у вас файл базы данных SQLite в браузере базы данных, который может заблокировать базу данных и вызвать эту ошибку (и часы гугления и раздражения).