java-如何设置向表中插入记录时的回滚功能?

ruyhziif  于 2021-06-17  发布在  Mysql
关注(0)|答案(1)|浏览(353)

我有一个程序,从一个pdf文件中提取一些记录,然后将这些记录插入mysql中的一个表中。
我主要关心的一个问题是,在插入到表的过程中,在任何情况下是否有错误。假设我将一个文件中的1000条记录插入到表中,中途发生了一些不好的事情。那么它是自动回滚还是我需要包含一个 "Begin Transaction and Commit Transaction" 声明?
如果是这样,如何在java内部启动回滚?我正在考虑编写一个回滚函数来实现这一点。
我的代码:

public void index(String path) throws Exception {

     PDDocument document = PDDocument.load(new File(path));
     if (!document.isEncrypted()) {
         PDFTextStripper tStripper = new PDFTextStripper();
         String pdfFileInText = tStripper.getText(document);
         String lines[] = pdfFileInText.split("\\r?\\n");
         for (String line : lines) {
             String[] words = line.split(" ");
             String sql="insert IGNORE into test.indextable values (?,?)";
             // con.connect().setAutoCommit(false);
             preparedStatement = con.connect().prepareStatement(sql);
             int i=0;
             for (String word : words) {
                 // check if one or more special characters at end of string then remove OR
                 // check special characters in beginning of the string then remove
                // insert every word directly to table db
                word=word.replaceAll("([\\W]+$)|(^[\\W]+)", "");
                preparedStatement.setString(1, path);
                preparedStatement.setString(2, word);
                preparedStatement.addBatch();
                i++;
                if (i % 1000 == 0) {
                    preparedStatement.executeBatch();
                    System.out.print("Add Thousand");
                }  
            }
            if (i > 0) {
                preparedStatement.executeBatch();
                System.out.print("Add Remaining");
            }

        }

    }

    // con.connect().commit();
    preparedStatement.close();
    System.out.println("Successfully commited changes to the database!");
}

上面的这个函数将被另一个要执行的函数调用,而try-and-catch异常在调用者函数中。
我的回滚功能:

// function to undo entries in inverted file on error indexing
 public void rollbackEntries() throws Exception {
     con.connect().rollback();
     System.out.println("Successfully rolled back changes from the database!");
 }

我很感激你的建议。

mwyxok5s

mwyxok5s1#

我不知道您使用的是什么库,所以我只想猜测异常名称和类型。如果您查看api,您可以查看哪些函数抛出了哪些异常。

private final static String INSERT_STATMENT = "insert IGNORE into test.indextable values (?,?)";

public void index(String path) { // Don't throw the exception, handle it.
     PDDocument document = null;
     try {
         document = PDDocument.load(new File(path));
     } catch (FileNotFoundException e) {
         System.err.println("Unable to find document \"" + path "\"!");
         return;
     }

     if (document == null || document.isEncrypted()) {
             System.err.println("Unable to read data from document \"" + path "\"!");
             return;
     }

     String[] lines = null;

     try {
         PDFTextStripper stripper = new PDFTextStripper(); 
         lines = stripper.getText(document).split("\\r?\\n");
     } catch (IOException e) {
         System.err.println("Could not read data from document \"" + path "\"! File may be corrupted!");
         return;
     }

     // You can add in extra checks just to test for other specific edge cases
     if (lines == null || lines.length < 2) {
         System.err.println("Only found 1 line in document \"" + path "\"! File may be corrupted!");
         return;
     }

     for (String line : lines) {
         PreparedStatement statement = con.connect().prepareStatement(INSERT_STATMENT );
             String[] words = line.split(" ");

             for (int index = 0, executeWait = 0; index < words.length; index++, executeWait++) {
                preparedStatement.setString(1, path);
                preparedStatement.setString(2, words[index].replaceAll("([\\W]+$)|(^[\\W]+)", ""));
                preparedStatement.addBatch();

                // Repeat this part again like before
                if (executeWait % 1000 == 0) {
                    for (int timeout = 0; true; timeout++) {
                        try {
                            preparedStatement.executeBatch();
                            System.out.print("Pushed " + (((executeWait - 1) % 1000) + 1) + " statements to database.");
                            break;
                        } catch (ConnectionLostException e) {
                            if (timeout >= 5) {
                                System.err.println("Unable to resolve issues! Exiting...");
                                return;
                            }
                            System.err.println("Lost connection to database! Fix attempt " + (timeout + 1) + ". (Timeout at 5)");
                            con.reconnect();
                        } catch (SqlWriteException error) {
                            System.err.println("Error while writing to database. Rolling back changes and retrying. Fix attempt " + (timeout + 1) + ". (Timeout at 5)");
                            rollbackEntries();
                            if (timeout >= 5) {
                                System.err.println("Unable to resolve issues! Exiting...");
                                return;
                            }
                        }
                    }
                }  
            }

        }

    try {
        preparedStatement.close();
    } catch (IOException e) {
        // Do nothing since it means it was already closed. 
        // Probably throws an exception to prevent people from calling this method twice.
    }
    System.out.println("Successfully committed all changes to the database!");
}

当然还有一些例外,你需要说明,我没有补充。
编辑:您的具体问题可以在这个链接找到

相关问题