【问题标题】:JDBC Transaction with user input带有用户输入的 JDBC 事务
【发布时间】:2015-05-19 23:35:29
【问题描述】:

我知道打开一个事务,等待用户输入和进行事务是一种非常糟糕的编程方式。但是,这是我正在做的一项课程作业所必需的 - 我们不允许更改已提供给我们的表格。

我正在使用具有 runQuery 和 update 方法的数据库访问类。为了使用事务,我创建了一个名为 commit transaction 的新方法 -

   public static void commitTransaction(String SQLStatement) throws SQLException,
            Exception {
        Connection dbConnect = DatabaseAccess.getConnection();

        PreparedStatement p = null;

        try {
            dbConnect.setAutoCommit(false);
            p = dbConnect.prepareStatement(SQLStatement);
        } catch (Exception e) {
            System.out.println("An error has occured");
        }

        p.executeUpdate();
        //dbConnect.setAutoCommit(true);
        dbConnect.close();
    }

由于 dbConnect.setAutoCommit(false),我创建了一个单独的函数,我认为需要在事务期间允许用户输入。我尝试创建的方法进行安全预订 - 启动事务,等待一堆输入,然后提交事务。我没有收到来自 java 的错误 - 但是没有任何内容添加到数据库中。

我认为我的事务可能未提交的一个原因是我在用户输入中运行查询。我需要输出这些查询的结果集 - 所以我没有使用禁用 autoCommit 的 commitTransaction 方法。这有什么问题吗?如果是这样,我该如何解决?

        //Start the transaction
        DatabaseAccess.commitTransaction("START TRANSACTION;");


        bookingID = BookingErrorChecks.createBookingID();

       /////////////////////////////////////////////
       //User inputs for flight they wish to book
       /////////////////////////////////////////////

        System.out.println("Showing available seats on your flight:");

        SQLStatement = "SELECT Flight.flightID, flightDate,\n"
                + "(MaxCapacity - SUM(NumSeats))\n"
                + "AS AvailableSeats FROM Flight JOIN\n"
                + " FlightBooking ON Flight.flightID =\n"
                + " FlightBooking.flightID\n"
                + "WHERE (Status = 'R' OR Status = 'H') AND Flight.flightID="
                + flightID
                + "GROUP BY Flight.flightID";

        answer = DatabaseAccess.runQuery(SQLStatement);


        /////////////////////////////////////////////
        //Prints out table of results 
        /////////////////////////////////////////////

        if (Integer.parseInt(availableSeats) < 1) 
        {
            System.out.println("There are no available seats, choose another"
                    + "flight");
            DatabaseAccess.commitTransaction("ROLLBACK");
        } else {
            save = DatabaseAccess.setSavepoint();
        }

       /////////////////////////////////////////////
       //User input for the number of seats and their first and last name
       /////////////////////////////////////////////

        SQLStatement = "SELECT customerID FROM LeadCustomer WHERE FirstName = '"
                + firstName + "' AND Surname = '" + lastName + "'";

        answer = DatabaseAccess.runQuery(SQLStatement);


        if (answer.next()) {
            customerID = answer.getInt("CustomerID");
        } else {
           /////////////////////////////////////////////
           //Create customer
           /////////////////////////////////////////////
        }

       /////////////////////////////////////////////
       //Final user inputs about the flight
       /////////////////////////////////////////////

 SQLStatement = "INSERT INTO FlightBooking values("
                + bookingID + "," + customerID + "," + flightID + ","
                + numSeats + ",'" + status + "','" + time + "',"
                + totalCost+")";
        DatabaseAccess.commitTransaction(SQLStatement);
        DatabaseAccess.commitTransaction("COMMIT TRANSACTION;");

        System.out.println("Flight Booking was sucessfully added.");
    }

}

【问题讨论】:

    标签: java postgresql jdbc transactions


    【解决方案1】:

    dbConnect.setAutoCommit(false); 之后,您需要调用dbConnect.commit() 或更改自动提交模式,如dbConnect.setAutoCommit(true);

    【讨论】:

    • 我该怎么做?如果我以相同的方法将自动提交设置为 true,那么它肯定会首先使自动提交无效吗?我刚刚尝试创建一个新方法public static void saveTransaction() throws SQLException, Exception { Connection dbConnect = DatabaseAccess.getConnection();` try { dbConnect.setAutoCommit(true); } catch (Exception e) { System.out.println("发生错误"); } } 但是当我调用它时,仍然没有提交
    • 您必须使用您第一次将自动提交设置为 false 的相同连接对象。如果您获得新连接,那么显然它将无法正常工作。您也可以尝试直接在同一个对象上调用 commit() 而不是更改自动提交模式。
    • 另请参考 setAutoCommit() 的 javadoc。 docs.oracle.com/javase/7/docs/api/java/sql/…
    猜你喜欢
    • 1970-01-01
    • 2014-07-18
    • 2018-02-03
    • 2016-01-03
    • 2015-09-28
    • 1970-01-01
    • 1970-01-01
    • 2017-10-05
    • 2017-07-30
    相关资源
    最近更新 更多