Я получаю код ошибки SQLITE_BUSY при попытке записи в таблицу после выбора из нее.Оператор выбора и результат правильно закрываются перед моей вставкой.
Если я удаляю выбранную часть, вставка работает нормально.И это то, что я не получаю.В соответствии с документацией SQLITE_BUSY должно означать, что другой процесс или соединение (что здесь определенно не так) блокирует базу данных.
Нет запущенного менеджера SQLite.Также jdbcConn
является единственным подключением к базе данных, которое у меня есть.Также нет параллельных потоков.
Вот мой код:
try {
if(!jdbcConn.isClosed()) {
ArrayList<String> variablesToAdd = new ArrayList<String>();
String sql = "SELECT * FROM VARIABLES WHERE Name = ?";
try (PreparedStatement stmt = jdbcConn.prepareStatement(sql)) {
for(InVariable variable : this.variables.values()) {
stmt.setString(1, variable.getName());
try(ResultSet rs = stmt.executeQuery()) {
if(!rs.next()) {
variablesToAdd.add(variable.getName());
}
}
}
}
if(variablesToAdd.size() > 0) {
String sqlInsert = "INSERT INTO VARIABLES(Name, Var_Value) VALUES(?, '')";
try(PreparedStatement stmtInsert = jdbcConn.prepareStatement(sqlInsert)) {
for(String name : variablesToAdd) {
stmtInsert.setString(1, name);
int affectedRows = stmtInsert.executeUpdate();
if(affectedRows == 0) {
LogManager.getLogger().error("Error while trying to add missing database variable '" + name + "'.");
}
}
}
jdbcConn.commit();
}
}
}
catch(Exception e) {
LogManager.getLogger().error("Error creating potentially missing database variables.", e);
}
Это происходит при int affectedRows = stmtInsert.executeUpdate();
.Теперь, если я удалю первый блок (и вручную добавлю значение в список variablesToAdd
), это значение будет вставлено в базу данных.
Я что-то упустил?Правильно ли я закрываю ResultSet и PreparedStatement?Может быть, я не замечаю своей ошибки, потому что смотрю на нее слишком долго.
Редактировать: Выполнение выбора в отдельном потоке делает свое дело.Но это не может быть решением.Пытаюсь ли я вставить в базу данных слишком быстро после закрытия предыдущих операторов?
Edit2: я столкнулся с busy_timeout, который обещал заставить обновления / запросы ждать определенное количество времени, прежде чем вернуться с SQLITE_BUSY.Я попытался установить тайм-аут занятости следующим образом:
if(jdbcConn.prepareStatement("PRAGMA busy_timeout = 30000").execute()) {
jdbcConn.commit();
}
Функция executeUpdate()
по-прежнему возвращается с SQLITE_BUSY.