Adding field to BatchUpdateException
Lance Andersen - Oracle
lance.andersen at oracle.com
Mon Nov 26 19:44:47 UTC 2012
Hi Joe,
Thank you for the sanity check.
I had added the following to the top of the javadoc (still playing with the wording):
As of Java SE 8, the method getLargeUpdateCount has been added to provide support for update counts that may be exceed Integer.MAX_VALUE and returned by the method Statement.executeLargeBatch. A JDBC driver implementation is required to throw BatchUpdateException(String reason, String SQLState, int vendorCode, long []updateCounts,Throwable cause) if an error occurs during the the execution of Statement.executeLargeBatch. If Statement.executeLargeBatch is invoked it is recommended that getLargeUpdateCounts be called instead of getUpdateCounts in order to avoid a possible overflow of the integer update count.
Best
Lance
On Nov 26, 2012, at 1:51 AM, Joe Darcy wrote:
> Hi Lance,
>
> I don't see an obvious problem with the code, but I strongly suggest documenting the correctness conditions regarding the updateCounts and longUpdateCounts fields; I think that would ease reviewing the new constructors and serialization code.
>
> Cheers,
>
> -Joe
>
> On 11/24/2012 2:05 PM, Lance Andersen - Oracle wrote:
>> Hi,
>>
>> For JDBC 4.2, I am adding methods to allow for larger update counts (request from JDBC driver vendors) and because of this I have to tweak BatchUpdateException
>>
>> The Statement interface has the method
>>
>> int[] executeBatch()
>>
>> I am planning to add
>>
>> long[] executeLargeBatch().
>>
>> To accomodate this change, I also need to add a new field and the method getLargeUpdateCount to BatchUpdateException.
>>
>> I have exchanged emails on this with Alan and he indicated that the changes seemed reasonable but to send a general email out to see if anything was missed from the serialization perspective.
>>
>> I have added JDBC Unit tests to validate that the serialization/deserialization works between JDBC 4.1 and JDBC 4.2 and they run without a problem.
>>
>>
>> Best
>> Lance
>>
>> new-host-2:sql lanceandersen$ diff BatchUpdateException.java ~/NetBeansProjects/JDBC4.2/jdbc4.0/src/java/sql/
>> 2c2
>> < * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
>> ---
>>> * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
>> 27a28,31
>>> import java.io.IOException;
>>> import java.io.InvalidObjectException;
>>> import java.io.ObjectInputStream;
>>> import java.io.ObjectOutputStream;
>> 83a88
>>> this.longUpdateCounts = (updateCounts == null) ? null : copyUpdateCount(updateCounts);
>> 192c197
>> < this((cause == null ? null : cause.toString()), null, 0, null, cause);
>> ---
>>> this((cause == null ? null : cause.toString()), null, 0, (int[])null, cause);
>> 295a301
>>> this.longUpdateCounts = (updateCounts == null) ? null : copyUpdateCount(updateCounts);
>> 331c337,401
>> <
>> ---
>>> /**
>>> * Constructs a <code>BatchUpdateException</code> object initialized with
>>> * a given <code>reason</code>, <code>SQLState</code>, <code>vendorCode</code>
>>> * <code>cause</code> and <code>updateCounts</code>.
>>> * <p>
>>> * This constructor should be used when the returned update count may exceed
>>> * {@link Integer.MAX_VALUE}.
>>> * <p>
>>> * @param reason a description of the error
>>> * @param SQLState an XOPEN or SQL:2003 code identifying the exception
>>> * @param vendorCode an exception code used by a particular
>>> * database vendor
>>> * @param updateCounts an array of <code>long</code>, with each element
>>> *indicating the update count, <code>Statement.SUCCESS_NO_INFO</code> or
>>> * <code>Statement.EXECUTE_FAILED</code> for each SQL command in
>>> * the batch for JDBC drivers that continue processing
>>> * after a command failure; an update count or
>>> * <code>Statement.SUCCESS_NO_INFO</code> for each SQL command in the batch
>>> * prior to the failure for JDBC drivers that stop processing after a command
>>> * failure
>>> * @param cause the underlying reason for this <code>SQLException</code>
>>> * (which is saved for later retrieval by the <code>getCause()</code> method);
>>> * may be null indicating the cause is non-existent or unknown.
>>> * @since 1.8
>>> */
>>> public BatchUpdateException(String reason, String SQLState, int vendorCode,
>>> long []updateCounts,Throwable cause) {
>>> super(reason, SQLState, vendorCode, cause);
>>> this.longUpdateCounts = (updateCounts == null) ? null : Arrays.copyOf(updateCounts, updateCounts.length);
>>> this.updateCounts = (longUpdateCounts == null) ? null : copyUpdateCount(longUpdateCounts);
>>> }
>>> /**
>>> * Retrieves the update count for each update statement in the batch
>>> * update that executed successfully before this exception occurred.
>>> * A driver that implements batch updates may or may not continue to
>>> * process the remaining commands in a batch when one of the commands
>>> * fails to execute properly. If the driver continues processing commands,
>>> * the array returned by this method will have as many elements as
>>> * there are commands in the batch; otherwise, it will contain an
>>> * update count for each command that executed successfully before
>>> * the <code>BatchUpdateException</code> was thrown.
>>> * <p>
>>> * This method should be used when the returned update count may exceed
>>> * {@link Integer.MAX_VALUE}.
>>> * <p>
>>> * @return an array of <code>long</code> containing the update counts
>>> * for the updates that were executed successfully before this error
>>> * occurred. Or, if the driver continues to process commands after an
>>> * error, one of the following for every command in the batch:
>>> * <OL>
>>> * <LI>an update count
>>> * <LI><code>Statement.SUCCESS_NO_INFO</code> to indicate that the command
>>> * executed successfully but the number of rows affected is unknown
>>> * <LI><code>Statement.EXECUTE_FAILED</code> to indicate that the command
>>> * failed to execute successfully
>>> * </OL>
>>> * @since 1.8
>>> */
>>> public long[] getLargeUpdateCounts() {
>>> return (longUpdateCounts == null) ? null :
>>> Arrays.copyOf(longUpdateCounts, longUpdateCounts.length);
>>> }
>>>
>> 337c407,414
>> < private final int[] updateCounts;
>> ---
>>> private int[] updateCounts;
>>>
>>> /**
>>> * The array that describes the outcome of a batch execution.
>>> * @serial
>>> * @since 1.8
>>> */
>>> private long[] longUpdateCounts;
>> 339a417,474
>>> /*
>>> * Utility method to copy int[] updateCount to long[] updateCount
>>> */
>>> private static long[] copyUpdateCount(int[] uc) {
>>> long[] copy = new long[uc.length];
>>> for(int i= 0; i< uc.length; i++) {
>>> copy[i] = uc[i];
>>> }
>>> return copy;
>>> }
>>> /*
>>> * Utility method to copy int[] updateCount to long[] updateCount
>>> */
>>> private static int[] copyUpdateCount(long[] uc) {
>>> int[] copy = new int[uc.length];
>>> for(int i= 0; i< uc.length; i++) {
>>> copy[i] = (int) uc[i];
>>> }
>>> return copy;
>>> }
>>> /**
>>> * readObject is called to restore the state of the
>>> * {@code BatchUpdateException} from a stream.
>>> */
>>> private void readObject(ObjectInputStream s)
>>> throws IOException, ClassNotFoundException {
>>> ObjectInputStream.GetField fields = s.readFields();
>>> int[] tmp = (int[])fields.get("updateCounts", null);
>>> long[] tmp2 = (long[])fields.get("longUpdateCounts", null);
>>> if(tmp != null && tmp2 != null && tmp.length != tmp2.length)
>>> throw new InvalidObjectException("update counts are not the expected size");
>>> if (tmp != null)
>>> updateCounts = tmp.clone();
>>> if (tmp2 != null)
>>> longUpdateCounts = tmp2.clone();
>>> if(updateCounts == null && longUpdateCounts != null)
>>> updateCounts = copyUpdateCount(longUpdateCounts);
>>> if(longUpdateCounts == null && updateCounts != null)
>>> longUpdateCounts = copyUpdateCount(updateCounts);
>>>
>>> }
>>> /**
>>> * writeObject is called to save the state of the {@code BatchUpdateException}
>>> * to a stream.
>>> */
>>> private void writeObject(ObjectOutputStream s)
>>> throws IOException, ClassNotFoundException {
>>>
>>> ObjectOutputStream.PutField fields = s.putFields();
>>> fields.put("updateCounts", updateCounts);
>>> fields.put("longUpdateCounts", longUpdateCounts);
>>> s.writeFields();
>>> }
>>
>>
>> Lance Andersen| Principal Member of Technical Staff | +1.781.442.2037
>> Oracle Java Engineering
>> 1 Network Drive
>> Burlington, MA 01803
>> Lance.Andersen at oracle.com
>>
>>
>
-------------- next part --------------
Lance Andersen| Principal Member of Technical Staff | +1.781.442.2037
Oracle Java Engineering
1 Network Drive
Burlington, MA 01803
Lance.Andersen at oracle.com
More information about the core-libs-dev
mailing list