У меня есть проблема, приведенный ниже код работает нормально, если я запускаю его без свойства autoCommit, однако я бы предпочел запустить его как транзакцию, код в основном вставляет информацию заголовка статьи, а затем перечисляет все связанные с ней статьи (так что это как отношения «один ко многим»), поэтому я мог бы зафиксировать все за один раз, а не сначала информацию о статье, а затем ее элементы. Проблема в том, что когда я дохожу до строки cn.commit(), я получаю исключение с надписью «Закрытое заявление».
метод вставки базы данных
public static void addArticle(Article article) throws SQLException {
Connection cn = null;
PreparedStatement ps = null;
StringBuffer insert = new StringBuffer();
StringBuffer itemsSQL = new StringBuffer();
try {
article.setArticleSortNum(getNextArticleNum(article.getShopId()));
article.setArticleId(DAOHelper.getNextId("article_id_sequence"));
cn = DBHelper.makeConnection();
cn.setAutoCommit(false);
insert.append("insert query for article goes here");
ps = cn.prepareStatement(insert.toString());
int i = 1;
ps.setLong(i, article.getArticleId()); i++;
ps.setLong(i, article.getShopId()); i++;
ps.setInt(i, article.getArticleNum()); i++;
// etcetera...
ps.executeUpdate();
itemsSQL.append("insert query for each line goes here");
itemStatement = cn.prepareStatement(itemsSQL.toString());
for(Article item : article.getArticlesList()) {
item.setArticleId(article.getArticleId());
i= 1;
itemStatement.setLong(i, item.getArticleId()); i++;
itemStatement.setInt(i, item.getItemsOnStock()); i++;
itemStatement.setInt(i, item.getQuantity()); i++;
// etcetera...
itemStatement.executeUpdate();
}
cn.commit();
} catch (SQLException e) {
cn.rollback();
log.error(e.getMessage());
throw e;
}
finally {
DBHelper.releasePreparedStatement(ps);
DBHelper.releasePreparedStatement(itemStatement);
DBHelper.releaseConnection(cn);
}
}
У меня также была вставка элементов, когда For работает с addBatch(), затем executeBatch, но также и та же ошибка Closed Statement при достижении cn.commit()... Я не понимаю, почему его закрытие, все соединения и все, наконец, освобождается пункта, так что у меня такое чувство, что я делаю какую-то фундаментальную ошибку, о которой я не знаю... Есть идеи? Заранее спасибо!
РЕДАКТИРОВАТЬ: Ниже приведена трассировка стека:
java.sql.SQLException: Закрытая инструкция в oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:189) в oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:231) в oracle.jdbc.dbaccess.DBError .throwSqlException(DBError.java:294) в oracle.jdbc.driver.OracleStatement.ensureOpen(OracleStatement.java:6226) в oracle.jdbc.driver.OraclePreparedStatement.sendBatch(OraclePreparedStatement.java:592) в oracle.jdbc.driver. OracleConnection.commit(OracleConnection.java:1376) на com.evermind.sql.FilterConnection.commit(FilterConnection.java:201) на com.evermind.sql.OrionCMTConnection.commit(OrionCMTConnection.java:461) на com.evermind.sql .FilterConnection.commit(FilterConnection.java:201) в com.dao.ArticlesDAO.addArticle(ArticlesDAO.java:571) в com.action.registry.CustomBaseAction.execute(CustomBaseAction.java:57) в org.apache.struts. action.RequestProcessor.processActionPerform(RequestProcessor.java:431) в org.apache.struts.action.RequestProce ssor.process(RequestProcessor.java:236) в org.apache.struts.action.ActionServlet.process(ActionServlet.java:1196) в org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432) в javax .servlet.http.HttpServlet.service(HttpServlet.java:760) в javax.servlet.http.HttpServlet.service(HttpServlet.java:853) в com.evermind.server.http.ServletRequestDispatcher.invoke(ServletRequestDispatcher.java:765) ) на com.evermind.server.http.ServletRequestDispatcher.forwardInternal(ServletRequestDispatcher.java:317) на com.evermind.server.http.HttpRequestHandler.processRequest(HttpRequestHandler.java:790) на com.evermind.server.http.HttpRequestHandler. run(HttpRequestHandler.java:270) на com.evermind.server.http.HttpRequestHandler.run(HttpRequestHandler.java:112) на com.evermind.util.ReleasableResourcePooledExecutor$MyWorker.run(ReleasableResourcePooledExecutor.java:192) на java.lang .Thread.run (неизвестный источник)
РЕДАКТИРОВАТЬ 2:
Это параметры в конфигурации источника данных драйвера, я думал, что процесс отладки может привести к тайм-ауту, но даже завершение менее чем за секунду вызывает исключение закрытого оператора
min-connections="20" max-connections="200" inactivity-timeout="20" stmt-cache-size="40"/>