Driver version
All (tested with 9.2.1 but same code is present in latest main branch).
Problem description
The normal behaviour of executeBatch is to clear the pending batch of operations, regardless of whether the batch execution completes successfully, succeeds for some rows and fails for others, or fails entirely with an exception:
|
} finally { |
|
batchParamValues = null; |
|
} |
(the code to reset batchParamValues to null is in a finally block and fires in all cases, even when an exception is thrown).
However, in the case where the bulk update API is used, batchParamValues is not cleared in the case of an exception:
|
bcOperation.writeToServer(batchRecord); |
|
bcOperation.close(); |
|
updateCounts = new int[batchParamValues.size()]; |
|
for (int i = 0; i < batchParamValues.size(); ++i) { |
|
updateCounts[i] = 1; |
|
} |
|
|
|
batchParamValues = null; |
|
loggerExternal.exiting(getClassNameLogging(), "executeBatch", updateCounts); |
|
return updateCounts; |
(batchParamValues = null is not in a finally so does not run if any of the bcOperation methods were to throw an exception). This means that subsequent addBatch calls following a failure will append to the existing batch rather than starting a new one, and the next executeBatch will re-submit the previous batch of rows along with the new data.
Expected behavior
The logic should be the same in all cases - executeBatch should always clear the batch state so subsequent addBatch calls begin a new batch.
Actual behavior
As described above - in the bulk update case the batch is not cleared on failure.
Any other details that can be helpful
Since clearBatch is idempotent, a workaround would be for user code to do an explicit stmt.clearBatch() call (in a finally) after every call to executeBatch().
Driver version
All (tested with 9.2.1 but same code is present in latest
mainbranch).Problem description
The normal behaviour of
executeBatchis to clear the pending batch of operations, regardless of whether the batch execution completes successfully, succeeds for some rows and fails for others, or fails entirely with an exception:mssql-jdbc/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerPreparedStatement.java
Lines 2174 to 2176 in d9a07bd
(the code to reset
batchParamValuestonullis in afinallyblock and fires in all cases, even when an exception is thrown).However, in the case where the bulk update API is used,
batchParamValuesis not cleared in the case of an exception:mssql-jdbc/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerPreparedStatement.java
Lines 2113 to 2122 in d9a07bd
(
batchParamValues = nullis not in afinallyso does not run if any of thebcOperationmethods were to throw an exception). This means that subsequentaddBatchcalls following a failure will append to the existing batch rather than starting a new one, and the nextexecuteBatchwill re-submit the previous batch of rows along with the new data.Expected behavior
The logic should be the same in all cases -
executeBatchshould always clear the batch state so subsequentaddBatchcalls begin a new batch.Actual behavior
As described above - in the bulk update case the batch is not cleared on failure.
Any other details that can be helpful
Since
clearBatchis idempotent, a workaround would be for user code to do an explicitstmt.clearBatch()call (in afinally) after every call toexecuteBatch().