Skip to content

Commit

Permalink
0003636: 3rd party triggers can affect SymmetricDS data load
Browse files Browse the repository at this point in the history
  • Loading branch information
mmichalek committed Jul 18, 2018
1 parent 59aef9b commit a2b0939
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 17 deletions.
Expand Up @@ -373,6 +373,8 @@ protected static SqlTemplateSettings createSqlTemplateSettings(TypedProperties p
settings.setReadStringsAsBytes(properties.is(ParameterConstants.JDBC_READ_STRINGS_AS_BYTES, false));
settings.setTreatBinaryAsLob(properties.is(ParameterConstants.TREAT_BINARY_AS_LOB_ENABLED, true));
settings.setRightTrimCharValues(properties.is(ParameterConstants.RIGHT_TRIM_CHAR_VALUES, false));
settings.setAllowUpdatesWithResults(properties.is(ParameterConstants.ALLOW_UPDATES_WITH_RESULTS, false));

LogSqlBuilder logSqlBuilder = new LogSqlBuilder();
logSqlBuilder.setLogSlowSqlThresholdMillis(properties.getInt(ParameterConstants.LOG_SLOW_SQL_THRESHOLD_MILLIS, 20000));
logSqlBuilder.setLogSqlParametersInline(properties.is(ParameterConstants.LOG_SQL_PARAMETERS_INLINE, true));
Expand Down
Expand Up @@ -435,6 +435,8 @@ private ParameterConstants() {

public final static String RIGHT_TRIM_CHAR_VALUES = "right.trim.char.values";

public final static String ALLOW_UPDATES_WITH_RESULTS = "allow.updates.with.results";

public final static String NODE_LOAD_ONLY = "load.only";

public final static String MYSQL_TINYINT_DDL_TO_BOOLEAN = "mysql.tinyint.ddl.to.boolean";
Expand Down
Expand Up @@ -2233,6 +2233,14 @@ treat.binary.as.lob.enabled=true
# Tags: other
right.trim.char.values=false

# When executing DML statements during data load, this controls whether executeUpdate or execute is used on the PreparedStatement. executeUpdate
# is used by default. execute() allows for unusual situations like when an application trigger generates a result set during an
# update statement.
#
# DatabaseOverridable: true
# Type: boolean
# Tags: other
allow.updates.with.results=false

# This is the location the staging directory will be put. If it isn't set the staging directory will be located according to java.io.tmpdir.
#
Expand Down
Expand Up @@ -31,6 +31,7 @@ public class SqlTemplateSettings {
protected int overrideIsolationLevel = -1;
protected int resultSetType = java.sql.ResultSet.TYPE_FORWARD_ONLY;
protected LogSqlBuilder logSqlBuilder;
protected boolean allowUpdatesWithResults = false;

public SqlTemplateSettings() {
}
Expand Down Expand Up @@ -107,4 +108,12 @@ public void setRightTrimCharValues(boolean rightTrimCharValues) {
this.rightTrimCharValues = rightTrimCharValues;
}

public boolean isAllowUpdatesWithResults() {
return allowUpdatesWithResults;
}

public void setAllowUpdatesWithResults(boolean allowUpdatesWithResults) {
this.allowUpdatesWithResults = allowUpdatesWithResults;
}

}
Expand Up @@ -329,18 +329,7 @@ public Integer execute(Connection con) throws SQLException {
try {
stmt = con.prepareStatement(sql);
jdbcSqlTemplate.setValues(stmt, args, types, jdbcSqlTemplate.getLobHandler().getDefaultHandler());

long startTime = System.currentTimeMillis();
boolean hasResults = stmt.execute();
long endTime = System.currentTimeMillis();
logSqlBuilder.logSql(log, sql, args, types, (endTime-startTime));

if (hasResults) {
rs = stmt.getResultSet();
while (rs.next()) {
}
}
return stmt.getUpdateCount();
return executePreparedUpdate(stmt, sql, args, types);
} catch (SQLException e) {
throw logSqlBuilder.logSqlAfterException(log, sql, args, e);
} finally {
Expand Down Expand Up @@ -468,17 +457,41 @@ public int addRow(Object marker, Object[] args, int[] argTypes) {
rowsUpdated = flush();
}
} else {
long start = System.currentTimeMillis();
pstmt.execute();
long end = System.currentTimeMillis();
logSqlBuilder.logSql(log, psql, args, argTypes, (end-start));
rowsUpdated = pstmt.getUpdateCount();
rowsUpdated = executePreparedUpdate(pstmt, psql, args, argTypes);
}
} catch (SQLException ex) {
throw jdbcSqlTemplate.translate(ex);
}
return rowsUpdated;
}

protected int executePreparedUpdate(PreparedStatement preparedStatement, String sql, Object[] args, int[] argTypes) throws SQLException {
int rowsUpdated = 0;
long start = System.currentTimeMillis();
if (jdbcSqlTemplate.getSettings().isAllowUpdatesWithResults()) {
rowsUpdated = executeAllowingResults(preparedStatement);
} else {
rowsUpdated = preparedStatement.executeUpdate();
}
long end = System.currentTimeMillis();
logSqlBuilder.logSql(log, psql, args, argTypes, (end-start));
return rowsUpdated;
}

protected int executeAllowingResults(PreparedStatement preparedStatement) throws SQLException {
int rowsUpdated = 0;
boolean hasResultsFlag = preparedStatement.execute();
int currentUpdateCount = preparedStatement.getUpdateCount();

while (hasResultsFlag || currentUpdateCount != -1) {
if (currentUpdateCount != -1) {
rowsUpdated += currentUpdateCount;
}
hasResultsFlag = preparedStatement.getMoreResults();
currentUpdateCount = preparedStatement.getUpdateCount();
}
return rowsUpdated;
}

public List<Object> getUnflushedMarkers(boolean clear) {
List<Object> ret = new ArrayList<Object>(markers);
Expand Down

0 comments on commit a2b0939

Please sign in to comment.