Update Batch

来源:互联网 发布:张北云计算基地 编辑:程序博客网 时间:2024/05/07 21:33

Note:

■Oracle recommends that you use JDBC standard features when

possible. This recommendation applies to update batching as well.

Oracle update batching is retained primarily for backwards

compatibility.

■For both standard update batching and Oracle update batching,

Oracle recommends you to keep the batch sizes in the general

range of 50 to 100. This is because though the drivers support

larger batches, they in turn result in a large memory footprint

with no corresponding increase in performance. Very large

batches usually result in a decline in performance compared to

smaller batches.

As implemented by Oracle, update batching is intended for use with prepared

statements, when you are repeating the same statement with different bind variables.

Be aware of the following:

1.Oracle update batching supports only prepared statement objects. For a callable
statement, both the connection default batch value and the statement batch value
are overridden with a value of 1. In an Oracle generic statement, there is no
statement batch value, and the connection default batch value is overridden with a
value of 1.
2.You can batch only UPDATE, INSERT, or DELETE operations. Processing a batch
that includes an operation that attempts to return a result set will cause an
exception.
Standard Update Batching
explicitly adding statements to the batch using an addBatch method and explicitly processing the batch using an executeBatch method. 
Adding Operations to the Batch
For prepared statements, update batching is used to batch multiple runs of the same
statement with different sets of bind parameters. For a PreparedStatement or
OraclePreparedStatement object, the addBatch method takes no input. It simply
adds the operation to the batch using the bind parameters last set by the appropriate
setXXX methods. 
For example:
复制代码
...
PreparedStatement pstmt
=
conn.prepareStatement(
"INSERT INTO employees VALUES(?, ?)");
pstmt.setInt(
1, 2000);
pstmt.setString(
2, "Milo Mumford");
pstmt.addBatch();
pstmt.setInt(
1, 3000);
pstmt.setString(
2, "Sulu Simpson");
pstmt.addBatch();
...
复制代码
At this point, two operations are in the batch.

Because a batch is associated with a single prepared statement object, you can batch

only repeated runs of a single prepared statement, as in this example.

Processing the Batch
To process the current batch of operations, use the executeBatch method of the
statement object. This method is specified in the standard Statement interface, which
is extended by the standard PreparedStatement and CallableStatement
interfaces.
Following is an example that repeats the prepared statement addBatch calls shown
previously and then processes the batch:
复制代码
...
PreparedStatement pstmt
=
conn.prepareStatement(
"INSERT INTO employees VALUES(?, ?)");
pstmt.setInt(
1, 2000);
pstmt.setString(
2, "Milo Mumford");
pstmt.addBatch();
pstmt.setInt(
1, 3000);
pstmt.setString(
2, "Sulu Simpson");
pstmt.addBatch();
int[] updateCounts = pstmt.executeBatch();
...
复制代码

  Starting from Oracle Database 11g Release 1 (11.1), the executeBatch method has

been improved so that when an error occurs in the middle of the batch execution, the

BatchUpdateExecution exception that is thrown contains the position of the error

in the batch. The BatchUpdateExecution.getUpdateCounts method returns an

array of int containing the update counts for the updates that were executed

successfully before this error occurred. So if an error occurs in the 5th element of the

batch, then the size of the array returned is 4 and each value is

Statement.SUCCESS_NO_INFO.

Committing the Changes in the Oracle Implementation of Standard Batching
After you process the batch, you must still commit the changes, presuming
auto-commit is disabled as recommended.
Calling commit, commits nonbatched operations and batched operations for
statement batches that have been processed, but for the Oracle implementation of
standard batching, has no effect on pending statement batches that have not been
processed
Clearing the Batch
To clear the current batch of operations instead of processing it, use the clearBatch
method of the statement object. This method is specified in the standard Statement
interface, which is extended by the standard PreparedStatement and
CallableStatement interfaces.
Keep the following things in mind:
■When a batch is processed, operations are performed in the order in which they
were batched.
■After calling addBatch, you must call either executeBatch or clearBatch
before a call to executeUpdate, otherwise there will be a SQL exception.
■A clearBatch or executeBatch call resets the statement batch to empty.
■The statement batch is not reset to empty if the connection receives a ROLLBACK
request. You must explicitly call clearBatch to reset it.
Note:
■If you are using Oracle update batching in Oracle Database 11g,
then you do not have to clear your batches explicitly in the code
after a rollback. However, it is OK to invoke clearBatch method
after a rollback.
■If you are using Oracle update batching in an earlier release, then
you have to invoke clearBatch method to clear your batches
explicitly after a rollback.
■Invoking clearBatch method after a rollback works for all releases.
■An executeBatch call closes the current result set of the statement object, if one exists.
■Nothing is returned by the clearBatch method.
Example 23–2 Standard Update Batching
This example combines the sample fragments in the previous sections, accomplishing
the following steps:
1. Disabling auto-commit mode, which you should always do when using either
  update batching model
2. Creating a prepared statement object
3. Adding operations to the batch associated with the prepared statement object
4. Processing the batch
5. Committing the operations from the batch
复制代码
conn.setAutoCommit(false);
PreparedStatement pstmt
=
conn.prepareStatement(
"INSERT INTO employees VALUES(?, ?)");
pstmt.setInt(
1, 2000);
pstmt.setString(
2, "Milo Mumford");
pstmt.addBatch();
pstmt.setInt(
1, 3000);
pstmt.setString(
2, "Sulu Simpson");
pstmt.addBatch();
int[] updateCounts = pstmt.executeBatch();
conn.commit();
pstmt.close();
...
复制代码

  You can process the update counts array to determine if the batch processed successfully.

Update Counts in the Oracle Implementation of Standard Batching

If a statement batch is processed successfully, then the integer array, or update counts

array, returned by the statement executeBatch call will always have one element for

each operation in the batch. In the Oracle implementation of standard update

batching, the values of the array elements are as follows:

■For a prepared statement batch, it is not possible to know the number of rows

affected in the database by each individual statement in the batch. Therefore, all

array elements have a value of -2. According to the JDBC 2.0 specification, a value

of -2 indicates that the operation was successful but the number of rows affected

is unknown.

Error Handling in the Oracle Implementation of Standard Batching
If any one of the batched operations fails to complete successfully or attempts to return
a result set during an executeBatch call, then the processing stops and a
java.sql.BatchUpdateException is generated.
After a batch exception, the update counts array can be retrieved using the
getUpdateCounts method of the BatchUpdateException object. This returns an
int array of update counts, just as the executeBatch method does. In the Oracle
implementation of standard update batching, contents of the update counts array are
as follows, after a batch is processed:
■For a prepared statement batch, it is not possible to know which operation failed.
The array has one element for each operation in the batch, and each element has a
value of -3. According to the JDBC 2.0 specification, a value of -3 indicates that
an operation did not complete successfully. In this case, it was presumably just one
operation that actually failed, but because the JDBC driver does not know which
operation that was, it labels all the batched operations as failures.
You should always perform a ROLLBACK operation in this situation.
my template
复制代码
 1              conn.setAutoCommit(false);
2 String sqlInsert="insert into friend(name) values(?)";
3 PreparedStatement pstmt=conn.prepareStatement(sqlInsert);
4 try {
5 pstmt.setNString(1, "friend1");
6 pstmt.addBatch();
7 pstmt.setNString(1, "friend2");
8 pstmt.addBatch();
9 pstmt.setNString(1, "friend3");
10 pstmt.addBatch();
11 int[] result = pstmt.executeBatch();
12 conn.commit();
13 } catch (BatchUpdateException e) {
14 //because it is impossible to know which operation failed.
15 //so there is no choice but to roll back the total batch update.
16 conn.rollback();
17 pstmt.clearBatch();
18 }
19 pstmt.close();
20 conn.close();
复制代码

 Of course, it would be better to put pstmt.close and conn.close into finally clause.

原创粉丝点击