Two different prepared statements in one single batch

前端 未结 4 745
梦毁少年i
梦毁少年i 2020-12-03 01:42

I want to send two different prepared statements in one single batch.

Currently I am doing this in two as you can see in the commented lines and it works,

相关标签:
4条回答
  • 2020-12-03 02:08

    You cannot execute two different statements in a single batch. As @dan mentioned you can -- and must -- do them in a single transaction.

    Another option is to use a stored procedure that can do it all in a single roundtrip to the server while maintaining the benefits of single transaction

    0 讨论(0)
  • 2020-12-03 02:08

    I think you may want to merge your statement queries as one and do something like this:

     String updateAccount= "UPDATE bankAccount 
                          SET if(? is not null ) 
                            then checkingBalance = checkingBalance - ? end if, 
                            if(? is not null ) 
                             then savingBalance = savingBalance + ? end if
                          WHERE id = ?";                
     PreparedStatement = dbConnection.prepareStatement(updateAccount);
    
     preparedStatement.setDouble(1, new Double(100));
     preparedStatement.setDouble(2, new Double(100));
     preparedStatement.setDouble(3, null);
     preparedStatement.setDouble(4, null);
     preparedStatement.setInt(5, 1);
     preparedStatement.addBatch();
    
     preparedStatement.setDouble(1, null);
     preparedStatement.setDouble(2, null);
     preparedStatement.setDouble(3, new Double(100));
     preparedStatement.setDouble(4, new Double(100));
     preparedStatement.setInt(5, 1);
     preparedStatement.addBatch();
     preparedStatement.executeBatch();
    
     dbConnection.commit();
    
    0 讨论(0)
  • 2020-12-03 02:15

    I am trying to utilize prepared statements and a batch! I say statements because I would like to send two prepared statements in one batch.

    When you're talking of PreparedStatement, a batch is associated with this PreparedStatement object's batch of commands and NOT the other way round. You should look at the javadoc for addBatch() method to know more about this.

    So in your case, here's what I would have done:

    • Created a new transaction and set a batch limit
    • Created a set of batch for each PreparedStatement and increment a batch counter
    • Executed the batch when I hit the limit and reset the counter
    • Committed my transaction once I'm done

    So your code would look something like this:

    preparedStatementWithdraw = connection.prepareStatement(....);
    preparedStatementDeposit  = connection.prepareStatement(....);
    boolean autoCommit        = connection.getAutoCommit();
    
    int batchLimit = 1000; //limit that you can vary
    int batchCounter = 0;
    try{
        connection.setAutoCommit(false);
    
        //set the params and start adding your batch statements, as per your requirement, something like
        preparedStatementWithdraw.addBatch();
        preparedStatementDeposit.addBatch();
        batchCounter++;
    
        if(batchCounter == batchLimit){
            try{
                preparedStatementWithdraw.executeBatch();
                preparedStatementDeposit.executeBatch();
            }catch(Exception exe){
                //log your error
            }finally{
                preparedStatementWithdraw.clearBatch();
                preparedStatementDeposit.clearBatch();
                batchCounter = 0;
            }
        }
    }finally{
            //process if any more statements are remaining in the batch
            try{
                preparedStatementWithdraw.executeBatch();
                preparedStatementDeposit.executeBatch();
            }catch(Exception exe){
                //log your error
            }finally{
                preparedStatementWithdraw.clearBatch();
                preparedStatementDeposit.clearBatch();
            }
    
        //1. depending on your requirement, commit/rollback the transation
        //2. Set autocommit to its original value
        connection.setAutoCommit(autoCommit);
        //3. Resoure management statements
    }
    
    0 讨论(0)
  • 2020-12-03 02:23

    You can try execute the two statement is a single transaction, like this:

    connection.setAutoCommit(false);
    try {
        stmt1.execute();
        stmt2.execute();
        connection.commit();
    } catch (Exception ex) {
        connection.rollback();
    }
    

    The issue is that addBatch works on a single prepared statement, see this is how you can use multiple sql statements with addBatch.

    0 讨论(0)
提交回复
热议问题