IDEMPIERE-497 2Pack SQL Statement Handler improvements for Postgresql. Use savepoint to rollback just the sql statement.

This commit is contained in:
Heng Sin Low 2013-08-15 01:04:47 +08:00
parent dcce7558b0
commit 7875807f04
1 changed files with 22 additions and 12 deletions

View File

@ -16,9 +16,9 @@
*****************************************************************************/ *****************************************************************************/
package org.adempiere.pipo2.handler; package org.adempiere.pipo2.handler;
import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Savepoint;
import java.sql.Statement; import java.sql.Statement;
import java.util.logging.Level; import java.util.logging.Level;
@ -33,6 +33,7 @@ import org.adempiere.pipo2.SQLElementParameters;
import org.compiere.model.X_AD_Package_Imp_Detail; import org.compiere.model.X_AD_Package_Imp_Detail;
import org.compiere.util.DB; import org.compiere.util.DB;
import org.compiere.util.Env; import org.compiere.util.Env;
import org.compiere.util.Trx;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl; import org.xml.sax.helpers.AttributesImpl;
@ -46,13 +47,17 @@ public class SQLStatementElementHandler extends AbstractElementHandler {
String sql = getStringValue(element, "statement"); String sql = getStringValue(element, "statement");
if (sql.endsWith(";") && !(sql.toLowerCase().endsWith("end;"))) if (sql.endsWith(";") && !(sql.toLowerCase().endsWith("end;")))
sql = sql.substring(0, sql.length() - 1); sql = sql.substring(0, sql.length() - 1);
Savepoint savepoint = null;
PreparedStatement pstmt = null; PreparedStatement pstmt = null;
try { try {
// NOTE Postgres needs to commit DDL statements // NOTE Postgres needs to commit DDL statements
// add a SQL command just with COMMIT if you want to simulate the Oracle behavior (commit on DDL) // add a SQL command just with COMMIT if you want to simulate the Oracle behavior (commit on DDL)
// Use savepoint here so that SQL exception would not rollback the whole process
// It is also necessary on postgres to add a COMMIT before any SQL statement that can fail if (DB.isPostgreSQL())
// for example a create index where is possible the index already exists {
Trx trx = Trx.get(getTrxName(ctx), true);
savepoint = trx.setSavepoint(null);
}
pstmt = DB.prepareStatement(sql, getTrxName(ctx)); pstmt = DB.prepareStatement(sql, getTrxName(ctx));
if (DBType.equals("ALL")) { if (DBType.equals("ALL")) {
@ -89,14 +94,13 @@ public class SQLStatementElementHandler extends AbstractElementHandler {
} catch (Exception e) { } catch (Exception e) {
if (DB.isPostgreSQL()) { if (DB.isPostgreSQL()) {
// rollback immediately postgres on exception to avoid a wrong SQL stop the whole process // rollback immediately postgres on exception to avoid a wrong SQL stop the whole process
if (pstmt != null) { if (savepoint != null)
Connection m_con = null; {
Trx trx = Trx.get(getTrxName(ctx), false);
try { try {
m_con = pstmt.getConnection(); trx.rollback(savepoint);
if (m_con != null && !m_con.getAutoCommit()) } catch (SQLException e1) {}
m_con.rollback(); savepoint = null;
} catch (SQLException ex) {
}
} }
} }
log.log(Level.SEVERE,"SQLSatement", e); log.log(Level.SEVERE,"SQLSatement", e);
@ -106,6 +110,12 @@ public class SQLStatementElementHandler extends AbstractElementHandler {
} finally { } finally {
DB.close(pstmt); DB.close(pstmt);
pstmt = null; pstmt = null;
if (savepoint != null) {
Trx trx = Trx.get(getTrxName(ctx), false);
try {
trx.releaseSavepoint(savepoint);
} catch (SQLException e) {}
}
} }
} }