Skip to content

Commit

Permalink
Avoid expensive Throwable.fillInStackTrace call on each batch execution
Browse files Browse the repository at this point in the history
  • Loading branch information
turbanoff committed Feb 2, 2024
1 parent 9378cfe commit f43c5df
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 24 deletions.
22 changes: 10 additions & 12 deletions h2/src/main/org/h2/jdbc/JdbcPreparedStatement.java
Original file line number Diff line number Diff line change
Expand Up @@ -1270,16 +1270,15 @@ public int[] executeBatch() throws SQLException {
batchIdentities = new MergedResult();
int size = batchParameters.size();
int[] result = new int[size];
SQLException exception = new SQLException();
ArrayList<SQLException> exceptions = new ArrayList<>();
checkClosed();
for (int i = 0; i < size; i++) {
long updateCount = executeBatchElement(batchParameters.get(i), exception);
long updateCount = executeBatchElement(batchParameters.get(i), exceptions);
result[i] = updateCount <= Integer.MAX_VALUE ? (int) updateCount : SUCCESS_NO_INFO;
}
batchParameters = null;
exception = exception.getNextException();
if (exception != null) {
throw new JdbcBatchUpdateException(exception, result);
if (!exceptions.isEmpty()) {
throw new JdbcBatchUpdateException(makeChain(exceptions), result);
}
return result;
} catch (Exception e) {
Expand All @@ -1304,23 +1303,22 @@ public long[] executeLargeBatch() throws SQLException {
batchIdentities = new MergedResult();
int size = batchParameters.size();
long[] result = new long[size];
SQLException exception = new SQLException();
ArrayList<SQLException> exceptions = new ArrayList<>();
checkClosed();
for (int i = 0; i < size; i++) {
result[i] = executeBatchElement(batchParameters.get(i), exception);
result[i] = executeBatchElement(batchParameters.get(i), exceptions);
}
batchParameters = null;
exception = exception.getNextException();
if (exception != null) {
throw new JdbcBatchUpdateException(exception, result);
if (!exceptions.isEmpty()) {
throw new JdbcBatchUpdateException(makeChain(exceptions), result);
}
return result;
} catch (Exception e) {
throw logAndConvert(e);
}
}

private long executeBatchElement(Value[] set, SQLException exception) {
private long executeBatchElement(Value[] set, ArrayList<SQLException> exceptions) {
ArrayList<? extends ParameterInterface> parameters = command.getParameters();
for (int i = 0, l = set.length; i < l; i++) {
parameters.get(i).setValue(set[i], false);
Expand All @@ -1332,7 +1330,7 @@ private long executeBatchElement(Value[] set, SQLException exception) {
ResultSet rs = super.getGeneratedKeys();
batchIdentities.add(((JdbcResultSet) rs).result);
} catch (Exception e) {
exception.setNextException(logAndConvert(e));
exceptions.add(logAndConvert(e));
updateCount = Statement.EXECUTE_FAILED;
}
return updateCount;
Expand Down
30 changes: 18 additions & 12 deletions h2/src/main/org/h2/jdbc/JdbcStatement.java
Original file line number Diff line number Diff line change
Expand Up @@ -805,22 +805,29 @@ public int[] executeBatch() throws SQLException {
}
int size = batchCommands.size();
int[] result = new int[size];
SQLException exception = new SQLException();
ArrayList<SQLException> exceptions = new ArrayList<>();
for (int i = 0; i < size; i++) {
long updateCount = executeBatchElement(batchCommands.get(i), exception);
long updateCount = executeBatchElement(batchCommands.get(i), exceptions);
result[i] = updateCount <= Integer.MAX_VALUE ? (int) updateCount : SUCCESS_NO_INFO;
}
batchCommands = null;
exception = exception.getNextException();
if (exception != null) {
throw new JdbcBatchUpdateException(exception, result);
if (!exceptions.isEmpty()) {
throw new JdbcBatchUpdateException(makeChain(exceptions), result);
}
return result;
} catch (Exception e) {
throw logAndConvert(e);
}
}

protected static SQLException makeChain(ArrayList<SQLException> exceptions) {
SQLException previous = exceptions.get(0);
for (int i = 1; i < exceptions.size(); i++) {
previous.setNextException(exceptions.get(i));
}
return exceptions.get(0);
}

/**
* Executes the batch.
* If one of the batched statements fails, this database will continue.
Expand All @@ -837,27 +844,26 @@ public long[] executeLargeBatch() throws SQLException {
}
int size = batchCommands.size();
long[] result = new long[size];
SQLException exception = new SQLException();
ArrayList<SQLException> exceptions = new ArrayList<>();
for (int i = 0; i < size; i++) {
result[i] = executeBatchElement(batchCommands.get(i), exception);
result[i] = executeBatchElement(batchCommands.get(i), exceptions);
}
batchCommands = null;
exception = exception.getNextException();
if (exception != null) {
throw new JdbcBatchUpdateException(exception, result);
if (!exceptions.isEmpty()) {
throw new JdbcBatchUpdateException(makeChain(exceptions), result);
}
return result;
} catch (Exception e) {
throw logAndConvert(e);
}
}

private long executeBatchElement(String sql, SQLException exception) {
private long executeBatchElement(String sql, ArrayList<SQLException> exceptions) {
long updateCount;
try {
updateCount = executeUpdateInternal(sql, null);
} catch (Exception e) {
exception.setNextException(logAndConvert(e));
exceptions.add(logAndConvert(e));
updateCount = Statement.EXECUTE_FAILED;
}
return updateCount;
Expand Down

0 comments on commit f43c5df

Please sign in to comment.