복붙노트

[SQL] 하나 개의 배치에서 두 개의 서로 다른 준비된 문

SQL

하나 개의 배치에서 두 개의 서로 다른 준비된 문

나는 하나 개의 배치에 두 개의 서로 다른 준비된 문을 보내려고합니다.

현재는 주석 라인에서 볼 수 있듯이 나는 두이 일을하고 그것은 작동하지만, 여기서는 그 주요 목적이 아니다. 사람이 일이 일을 얻기 위해 그 의견 대신에 무엇을 넣어 말해 줄래?

import java.lang.ClassNotFoundException;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.DriverManager;

public class Main
{
    public static void main(String[] args)
    {
        Connection connection = null;
        PreparedStatement preparedStatementWithdraw = null;
        PreparedStatement preparedStatementDeposit = null;

        try
        {
            Class.forName("com.mysql.jdbc.Driver");
            connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/youtube", "root", "root");

            preparedStatementWithdraw = withdrawFromChecking(connection, preparedStatementWithdraw, new BigDecimal(100), 1);
            preparedStatementDeposit = depositIntoSaving(connection, preparedStatementDeposit, new BigDecimal(300), 1);

            //preparedStatementDeposit.executeBatch();
            //preparedStatementWithdraw.executeBatch();
            System.out.println("Account Modified!");
        }
        catch(ClassNotFoundException error)
        {
            System.out.println("Error: " + error.getMessage());
        }
        catch(SQLException error)
        {
            System.out.println("Error: " + error.getMessage());
        }
        finally
        {
            if(connection != null) try{connection.close();} catch(SQLException error) {}
            if(preparedStatementDeposit != null) try{preparedStatementDeposit.close();} catch(SQLException error) {}
        }
    }

    public static PreparedStatement withdrawFromChecking(Connection connection, PreparedStatement preparedStatement, BigDecimal balance, int id) throws SQLException
    {
        preparedStatement = connection.prepareStatement("UPDATE bankAccount SET checkingBalance = checkingBalance - ? WHERE id = ?");
        preparedStatement.setBigDecimal(1, balance);
        preparedStatement.setInt(2, id);
        preparedStatement.addBatch();

        return preparedStatement;
    }

    public static PreparedStatement depositIntoSaving(Connection connection, PreparedStatement preparedStatement, BigDecimal balance, int id) throws SQLException
    {
        preparedStatement = connection.prepareStatement("UPDATE bankAccount SET savingBalance = savingBalance + ? WHERE id = ?");
        preparedStatement.setBigDecimal(1, balance);
        preparedStatement.setInt(2, id);
        preparedStatement.addBatch();

        return preparedStatement;
    }
}

해결법

  1. ==============================

    1.당신은 하나의 배치에 두 개의 서로 다른 문을 실행할 수 없습니다. 해야 - - @dan은 당신이 할 수있는 언급 한 바와 같이 단일 트랜잭션을 수행.

    당신은 하나의 배치에 두 개의 서로 다른 문을 실행할 수 없습니다. 해야 - - @dan은 당신이 할 수있는 언급 한 바와 같이 단일 트랜잭션을 수행.

    또 다른 옵션은 단일 트랜잭션의 장점을 유지하면서 서버에 하나의 왕복에 모든 것을 할 수있는 저장 프로 시저를 사용하는 것입니다

  2. ==============================

    2.당신은 두 개의 문은 다음과 같은 단일 트랜잭션입니다 실행 시도 할 수 있습니다 :

    당신은 두 개의 문은 다음과 같은 단일 트랜잭션입니다 실행 시도 할 수 있습니다 :

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

    문제는 addBatch가 하나의 준비된 명령문에서 작동이 당신이 addBatch 여러 SQL 문을 사용하는 방법입니다 볼 수 있다는 것입니다.

  3. ==============================

    3.당신의 PreparedStatement의 얘기하면, 일괄이 PreparedStatement 오브젝트의 명령의 배치 및 NOT 다른 방법 라운드와 연결되어 있습니다. addBatch () 메소드가 더 이것에 대해 아는 당신은 javadoc에보고해야한다.

    당신의 PreparedStatement의 얘기하면, 일괄이 PreparedStatement 오브젝트의 명령의 배치 및 NOT 다른 방법 라운드와 연결되어 있습니다. addBatch () 메소드가 더 이것에 대해 아는 당신은 javadoc에보고해야한다.

    따라서 귀하의 경우, 여기에 내가했을 것입니다 :

    코드는 다음과 같이 보일 것입니다 그래서 :

    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
    }
    
  4. ==============================

    4.난 당신이 하나 명세서 쿼리를 병합하고 이런 일을 수행 할 수 있습니다 생각 :

    난 당신이 하나 명세서 쿼리를 병합하고 이런 일을 수행 할 수 있습니다 생각 :

     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();
    
  5. from https://stackoverflow.com/questions/12977568/two-different-prepared-statements-in-one-single-batch by cc-by-sa and MIT license