Closed hlms closed 6 months ago
Adding some more detail:
st.executeLargeUpdate(bulkInsertQuery)
returns a long
value.
Attempted to check the behaviour of this when the first batch fails, second batch fails and when the third batch fails.
When the first batch itself fails, the statement throws exception as expected:
2024-03-14 14:18:22 2024-03-14 08:48:22,912+0000 [toe=acgubk80vow677] [Pool Worker - 55] [,,] ERROR - Violation of UNIQUE KEY constraint 'UQ__ST_Order__E65CA761D1FED3F3'. Cannot insert duplicate key in object 'S_bcabbbbf_7118_48dc_a0e0_bbd075ce01de.ST_Orders'. The duplicate key value is (11065). com.microsoft.sqlserver.jdbc.SQLServerException: Violation of UNIQUE KEY constraint 'UQ__ST_Order__E65CA761D1FED3F3'. Cannot insert duplicate key in object 'S_bcabbbbf_7118_48dc_a0e0_bbd075ce01de.ST_Orders'. The duplicate key value is (11065).
2024-03-14 14:18:22 at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:259) ~[mssql-jdbc-12.4.2.jre11.jar:?]
2024-03-14 14:18:22 at com.microsoft.sqlserver.jdbc.TDSTokenHandler.onEOF(tdsparser.java:304) ~[mssql-jdbc-12.4.2.jre11.jar:?]
2024-03-14 14:18:22 at com.microsoft.sqlserver.jdbc.TDSParser.parse(tdsparser.java:137) ~[mssql-jdbc-12.4.2.jre11.jar:?]
2024-03-14 14:18:22 at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1691) ~[mssql-jdbc-12.4.2.jre11.jar:?]
2024-03-14 14:18:22 at com.microsoft.sqlserver.jdbc.SQLServerStatement.doExecuteStatement(SQLServerStatement.java:920) ~[mssql-jdbc-12.4.2.jre11.jar:?]
2024-03-14 14:18:22 at com.microsoft.sqlserver.jdbc.SQLServerStatement$StmtExecCmd.doExecute(SQLServerStatement.java:814) ~[mssql-jdbc-12.4.2.jre11.jar:?]
2024-03-14 14:18:22 at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:7675) ~[mssql-jdbc-12.4.2.jre11.jar:?]
2024-03-14 14:18:22 at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:4137) ~[mssql-jdbc-12.4.2.jre11.jar:?]
2024-03-14 14:18:22 at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:272) ~[mssql-jdbc-12.4.2.jre11.jar:?]
2024-03-14 14:18:22 at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:246) ~[mssql-jdbc-12.4.2.jre11.jar:?]
2024-03-14 14:18:22 at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeLargeUpdate(SQLServerStatement.java:774) ~[mssql-jdbc-12.4.2.jre11.jar:?]
st.executeLargeUpdate(bulkInsertQuery)
returns 400 (size of first batch).
No exception is thrown.
When does jdbc driver return control to the caller / java application?
Hi @hlms,
I'm not familiar with expected behavior of the driver in this scenario. We'll investigate further and get back to you with an answer/resolution.
This is actually a common scenario and we have wiki/MS doc pages for it: https://docs.microsoft.com/en-us/sql/connect/jdbc/parsing-the-results?view=sql-server-ver16 https://github.com/microsoft/mssql-jdbc/wiki/Handling-SQLExceptions
You can also see previous issues - #367, #399, #826, #937, #995, #1171
Therefore, this is expected driver behavior. Please let us know if you have any further questions, if not we will be closing the issue.
I'm yet to go through the provided links in detail.
What about introducing a new argument (e.g. RAISE_FAILURES) for Bulk insert (similar to BATCHSIZE argument)? So that if users want bulk insert to surface failure in insertion of any of the batches, then based on this parameter, the driver would raise failures.
The point is - SQL server raises the errors. Shouldn't the driver pass the response as-is instead of swallowing something?
Driver version
Provide the JDBC driver version: mssql-jdbc.12.4.2.jre11.jar
SQL Server version
Provide the output of executing
SELECT @@VERSION
on your target SQL Server:SQL server is running inside docker 4.27.2.
Client Operating System
Provide the Operating System the client application is running on: Windows 11 enterprise
JAVA/JVM version
Provide the JAVA/JVM version (e.g. java version "1.8.0").
Table schema
Provide the table schema to repro the issue:
Problem description
With bulk insert command execution through jdbc driver, when batchsize is used, if insertion for any batch (probably second batch onwards) fails, the jdbc driver can't detect the failure. It responds as success to the caller.
Steps to reproduce the issue
// Notice that aforementioned query has BATCHSIZE=400, and the number of records are 830 in the file. So it will execute in three batches: 400 + 400 + 30.
st.executeLargeUpdate(bulkInsertQuery);
So looks like the driver just reads the first message of response and NOT the further messages (response from SQL server).
I haven't yet tried failing the first batch itself.
JDBC trace logs
Provide the JDBC driver trace logs. Instructions can be found here: https://docs.microsoft.com/sql/connect/jdbc/tracing-driver-operation