Java 如何一次回滚插入到3个表中的数据?

Java 如何一次回滚插入到3个表中的数据?,java,mysql,sql,jdbc,prepared-statement,Java,Mysql,Sql,Jdbc,Prepared Statement,请看下面的代码 DBHandler.java @Override public String insertClient(String name, String address, String phone, String email, String country, Date visaGrantedDate, Date visaEntryDate) { int i=0; try { con.setAutoComm

请看下面的代码

DBHandler.java

 @Override
    public String insertClient(String name, String address, String phone, String email, String country, Date visaGrantedDate, Date visaEntryDate)
    {
         int i=0;
       try
       {
           con.setAutoCommit(false);
           PreparedStatement ps = con.prepareStatement("insert into Client (Name, Address, Phone, Email, Country, Visa_Granted_Date, Visa_Entry_Date) values (?,?,?,?,?,?,?)");
           ps.setString(1,name);
           ps.setString(2,address);
           ps.setString(3,phone);
           ps.setString(4, email);
           ps.setString(5, country);
           ps.setDate(6, visaGrantedDate);
           ps.setDate(7, visaEntryDate);

           i = ps.executeUpdate();
           con.commit();

           if(i>0)
           {
               return "Data saved successfully";
           }
           else
           {
               return "Error in saving data";
           }
       }
       catch(SQLException e)
       {
           try
           {
               con.rollback();
               e.printStackTrace();
               return "Failed to save data. Data safely rolled back";
           }
           catch(Exception ee)
           {
               ee.printStackTrace();
               return "Failed to save data. Data roll back failed";
           }
       }
    }

    @Override
    public String insertPortfolio(String portfolioID, String clientName, double amount, double dicn, String lawyer, String introducer, String provider, String Types)
    {
        int i=0;
       try
       {
           con.setAutoCommit(false);
           PreparedStatement ps = con.prepareStatement("insert into Portfolio (portfolio_id, Client_Name, Amount, riteria_Net, Lawyer, Introducer, Provider, Types) values (?,?,?,?,?,?,?,?)");
           ps.setString(1,portfolioID);
           ps.setString(2,clientName);
           ps.setDouble(3,amount);
           ps.setDouble(4, dicn);
           ps.setString(5, lawyer);
           ps.setString(6, introducer);
           ps.setString(7, provider);
           ps.setString(8, Types);

           i = ps.executeUpdate();
           con.commit();

           if(i>0)
           {
               return "Data saved successfully";
           }
           else
           {
               return "Error in saving data";
           }
       }
       catch(SQLException e)
       {
           try
           {
               con.rollback();
               e.printStackTrace();
               return "Failed to save data. Data safely rolled back";
           }
           catch(Exception ee)
           {
               ee.printStackTrace();
               return "Failed to save data. Data roll back failed";
           }
       }
    }

    @Override
    public String insertClientFees(String portfolioID, double initialFees, double initialStepnaFees, double initialIntraFees, double ongoingFees, double ongoingStepnaFees, double ongoingIntraFees, double ongoingFabulaFees, double Fees, double otherFees, double VAT) 
    {
         int i=0;
       try
       {
           con.setAutoCommit(false);
           PreparedStatement ps = con.prepareStatement("insert into Client_Fees (portfolio_id, Initial_Fees, InitiaFees2, Initial_intra_Fees, Ongoing_Fees, Ongoing_octa_Fees, Ongoing_intra_Fees, Ongoing_fabula_Fees, Ongoing_stepna_Fees, Other, VAT) values (?,?,?,?,?,?,?,?,?,?,?)");
           ps.setString(1,portfolioID);
           ps.setDouble(2,initialintraFees); 
           //Rest of the data insert code has been removed


           i = ps.executeUpdate();
           con.commit();

           if(i>0)
           {
               return "Data saved successfully";
           }
           else
           {
               return "Error in saving data";
           }
       }
       catch(SQLException e)
       {
           try
           {
               con.rollback();
               e.printStackTrace();
               return "Failed to save data. Data safely rolled back";
           }
           catch(Exception ee)
           {
               ee.printStackTrace();
               return "Failed to save data. Data roll back failed";
           }
       }
    }
dbConnector.insertClient(name, address, phone, email, country, null, null);

dbConnector.insertPortfolio(clientPortfolioId, name, amount, dicn, name, country, phone, visaEntryDate);

dbConnector.insertClientFees(clientPortfolioId, initialFees, initialVisionFees, initialintraFees, ongoingFees, ongoingStepnaFees, ongoingIntraFees, ongoingFabulaFees, ongoingserFees, otherFees, VAT)
您刚才在上面的代码中看到的是如何将数据插入同一数据库中的3个不同表中。但是,所有这3个表的“表单字段”都包含在一个表单中,因此所有这些表都应该立即更新,如果发生什么情况,则应该回滚刚刚插入到所有这3个表中的数据。例如,下面是如何调用数据库代码

MainUI.java

 @Override
    public String insertClient(String name, String address, String phone, String email, String country, Date visaGrantedDate, Date visaEntryDate)
    {
         int i=0;
       try
       {
           con.setAutoCommit(false);
           PreparedStatement ps = con.prepareStatement("insert into Client (Name, Address, Phone, Email, Country, Visa_Granted_Date, Visa_Entry_Date) values (?,?,?,?,?,?,?)");
           ps.setString(1,name);
           ps.setString(2,address);
           ps.setString(3,phone);
           ps.setString(4, email);
           ps.setString(5, country);
           ps.setDate(6, visaGrantedDate);
           ps.setDate(7, visaEntryDate);

           i = ps.executeUpdate();
           con.commit();

           if(i>0)
           {
               return "Data saved successfully";
           }
           else
           {
               return "Error in saving data";
           }
       }
       catch(SQLException e)
       {
           try
           {
               con.rollback();
               e.printStackTrace();
               return "Failed to save data. Data safely rolled back";
           }
           catch(Exception ee)
           {
               ee.printStackTrace();
               return "Failed to save data. Data roll back failed";
           }
       }
    }

    @Override
    public String insertPortfolio(String portfolioID, String clientName, double amount, double dicn, String lawyer, String introducer, String provider, String Types)
    {
        int i=0;
       try
       {
           con.setAutoCommit(false);
           PreparedStatement ps = con.prepareStatement("insert into Portfolio (portfolio_id, Client_Name, Amount, riteria_Net, Lawyer, Introducer, Provider, Types) values (?,?,?,?,?,?,?,?)");
           ps.setString(1,portfolioID);
           ps.setString(2,clientName);
           ps.setDouble(3,amount);
           ps.setDouble(4, dicn);
           ps.setString(5, lawyer);
           ps.setString(6, introducer);
           ps.setString(7, provider);
           ps.setString(8, Types);

           i = ps.executeUpdate();
           con.commit();

           if(i>0)
           {
               return "Data saved successfully";
           }
           else
           {
               return "Error in saving data";
           }
       }
       catch(SQLException e)
       {
           try
           {
               con.rollback();
               e.printStackTrace();
               return "Failed to save data. Data safely rolled back";
           }
           catch(Exception ee)
           {
               ee.printStackTrace();
               return "Failed to save data. Data roll back failed";
           }
       }
    }

    @Override
    public String insertClientFees(String portfolioID, double initialFees, double initialStepnaFees, double initialIntraFees, double ongoingFees, double ongoingStepnaFees, double ongoingIntraFees, double ongoingFabulaFees, double Fees, double otherFees, double VAT) 
    {
         int i=0;
       try
       {
           con.setAutoCommit(false);
           PreparedStatement ps = con.prepareStatement("insert into Client_Fees (portfolio_id, Initial_Fees, InitiaFees2, Initial_intra_Fees, Ongoing_Fees, Ongoing_octa_Fees, Ongoing_intra_Fees, Ongoing_fabula_Fees, Ongoing_stepna_Fees, Other, VAT) values (?,?,?,?,?,?,?,?,?,?,?)");
           ps.setString(1,portfolioID);
           ps.setDouble(2,initialintraFees); 
           //Rest of the data insert code has been removed


           i = ps.executeUpdate();
           con.commit();

           if(i>0)
           {
               return "Data saved successfully";
           }
           else
           {
               return "Error in saving data";
           }
       }
       catch(SQLException e)
       {
           try
           {
               con.rollback();
               e.printStackTrace();
               return "Failed to save data. Data safely rolled back";
           }
           catch(Exception ee)
           {
               ee.printStackTrace();
               return "Failed to save data. Data roll back failed";
           }
       }
    }
dbConnector.insertClient(name, address, phone, email, country, null, null);

dbConnector.insertPortfolio(clientPortfolioId, name, amount, dicn, name, country, phone, visaEntryDate);

dbConnector.insertClientFees(clientPortfolioId, initialFees, initialVisionFees, initialintraFees, ongoingFees, ongoingStepnaFees, ongoingIntraFees, ongoingFabulaFees, ongoingserFees, otherFees, VAT)

因此,我的问题是,如果出现问题,如何一次回滚刚刚插入到所有3个表中的数据?

您当前有3个事务,每个方法中有一个事务。您需要有一个事务(一个
setAutoCommit(false)
和一个
commit()
rollback()


因此,您需要相应地重构代码。

您只需向上推
试试……从它们之外的方法捕获
块:

try {
     con.setAutoCommit(false);

     dbConnector.insertClient(...
     dbConnector.insertPortfolio(...
     dbConnector.insertClientFees(...

     con.commit();
} catch(SQLException e) {
     try {
          con.rollback();
          e.printStackTrace();
           return "Failed to save data. Data safely rolled back";
     } 
     ...
}
您的con.setAutoCommit(错误);很好,但您不能执行con.commit();这是在每3个函数通过之前

try {
  dbConnector.disableAutoCommit();
  dbConnector.insertClient(name, address, phone, email, country, null, null);

  dbConnector.insertPortfolio(clientPortfolioId, name, amountInvested, dicn, name, country, phone, visaEntryDate);

  dbConnector.insertClientFees(clientPortfolioId, initialEdenhurstFees, initialVisionFees, initialIntroducerFees, ongoingEdenhurstFees, ongoingVisionFees, ongoingIntroducerFees, ongoingCastleFees, ongoingEdenCastleFees, otherFees, VAT)

  dbConnector.commit();
} catch(Esxception e) {
  dbConnector.rollback();
}

更像这样,您的插入函数不应该执行setAutocommit(false)和commit(),rollback()之类的操作,也不应该捕获异常本身

您应该使用
事务
:只需回滚事务您应该使用相同的
连接
实例来执行所有三条语句。然后调用
commit()
rollback()
一次。每次调用
commit()。但是如果变量
i
小于或等于0怎么办?@希望如此,在这种情况下也可以执行回滚。好的,不管怎样,它可以不惜任何代价小于0吗?如果是,那么我当然必须实施回滚,如果这不是一个负责任的问题,那么我就没有什么可担心的了。