Có những lúc bạn không muốn một câu lệnh có hiệu lực trừ khi một câu lệnh khác hoàn thành. Ví dụ, khi chủ sở hữu The Coffee Break cập nhật số lượng cà phê bán ra mỗi tuần, chủ sở hữu cũng sẽ muốn cập nhật tổng số lượng cà phê đã bán cho đến thời điểm hiện tại. Tuy nhiên, số lượng đã bán mỗi tuần và tổng số lượng đã bán nên được cập nhật cùng một lúc; . Cách để đảm bảo rằng cả hai hành động xảy ra hoặc không hành động nào xảy ra là sử dụng một giao dịch. Một giao dịch là một tập hợp gồm một hoặc nhiều câu lệnh được thực thi dưới dạng một đơn vị, do đó, tất cả các câu lệnh đều được thực hiện hoặc không có câu lệnh nào được thực hiện
Trang này bao gồm các chủ đề sau
Khi một kết nối được tạo, nó ở chế độ tự động cam kết. Điều này có nghĩa là mỗi câu lệnh SQL riêng lẻ được coi là một giao dịch và được tự động cam kết ngay sau khi nó được thực thi. [Nói chính xác hơn, mặc định là một câu lệnh SQL được cam kết khi hoàn thành, không phải khi nó được thực thi. Một câu lệnh được hoàn thành khi tất cả các tập kết quả và số lần cập nhật của nó đã được truy xuất. Tuy nhiên, trong hầu hết các trường hợp, một câu lệnh được hoàn thành và do đó được thực hiện ngay sau khi nó được thực thi. ]
Cách cho phép hai hoặc nhiều câu lệnh được nhóm vào một giao dịch là tắt chế độ tự động cam kết. Điều này được thể hiện trong đoạn mã sau, trong đó
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }3 là một kết nối đang hoạt động
con.setAutoCommit[false];
Sau khi chế độ tự động cam kết bị tắt, không có câu lệnh SQL nào được cam kết cho đến khi bạn gọi phương thức
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }4 một cách rõ ràng. Tất cả các câu lệnh được thực thi sau lệnh gọi phương thức
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }4 trước đó được bao gồm trong giao dịch hiện tại và được cam kết cùng nhau dưới dạng một đơn vị. Phương pháp sau đây,
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }6, trong đó
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }3 là một kết nối đang hoạt động, minh họa một giao dịch
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }
Trong phương pháp này, chế độ tự động cam kết bị vô hiệu hóa cho kết nối
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }3, có nghĩa là hai câu lệnh đã chuẩn bị sẵn là
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }1 và
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }2 được cam kết cùng nhau khi phương thức
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }4 được gọi. Bất cứ khi nào phương thức
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }4 được gọi [tự động khi chế độ tự động cam kết được bật hoặc rõ ràng khi chế độ này bị tắt], tất cả các thay đổi do các câu lệnh trong giao dịch đều được thực hiện vĩnh viễn. Trong trường hợp này, điều đó có nghĩa là các cột
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }5 và
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }6 cho cà phê Colombia đã được thay đổi thành
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }7 [nếu trước đó
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }6 là
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }9] và sẽ giữ nguyên giá trị này cho đến khi chúng được thay đổi bằng một câu lệnh cập nhật khác
Câu lệnh
public void modifyPricesByPercentage[ String coffeeName, float priceModifier, float maximumPrice] throws SQLException { con.setAutoCommit[false]; ResultSet rs = null; String priceQuery = "SELECT COF_NAME, PRICE FROM COFFEES " + "WHERE COF_NAME = ?"; String updateQuery = "UPDATE COFFEES SET PRICE = ? " + "WHERE COF_NAME = ?"; try [PreparedStatement getPrice = con.prepareStatement[priceQuery, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY]; PreparedStatement updatePrice = con.prepareStatement[updateQuery]] { Savepoint save1 = con.setSavepoint[]; getPrice.setString[1, coffeeName]; if [!getPrice.execute[]] { System.out.println["Could not find entry for coffee named " + coffeeName]; } else { rs = getPrice.getResultSet[]; rs.first[]; float oldPrice = rs.getFloat["PRICE"]; float newPrice = oldPrice + [oldPrice * priceModifier]; System.out.printf["Old price of %s is $%.2f%n", coffeeName, oldPrice]; System.out.printf["New price of %s is $%.2f%n", coffeeName, newPrice]; System.out.println["Performing update..."]; updatePrice.setFloat[1, newPrice]; updatePrice.setString[2, coffeeName]; updatePrice.executeUpdate[]; System.out.println["\nCOFFEES table after update:"]; CoffeesTable.viewTable[con]; if [newPrice > maximumPrice] { System.out.printf["The new price, $%.2f, is greater " + "than the maximum price, $%.2f. " + "Rolling back the transaction...%n", newPrice, maximumPrice]; con.rollback[save1]; System.out.println["\nCOFFEES table after rollback:"]; CoffeesTable.viewTable[con]; } con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; } finally { con.setAutoCommit[true]; } }0 kích hoạt chế độ tự động cam kết, có nghĩa là mỗi câu lệnh một lần nữa được tự động cam kết khi hoàn thành. Sau đó, bạn quay lại trạng thái mặc định nơi bạn không phải tự gọi phương thức
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }4. Chỉ nên tắt chế độ tự động cam kết trong chế độ giao dịch. Bằng cách này, bạn tránh giữ khóa cơ sở dữ liệu cho nhiều câu lệnh, điều này làm tăng khả năng xung đột với những người dùng khác
Ngoài việc nhóm các câu lệnh lại với nhau để thực thi dưới dạng một đơn vị, các giao dịch có thể giúp duy trì tính toàn vẹn của dữ liệu trong một bảng. Chẳng hạn, hãy tưởng tượng rằng một nhân viên có nhiệm vụ nhập giá cà phê mới vào bảng
public void modifyPricesByPercentage[ String coffeeName, float priceModifier, float maximumPrice] throws SQLException { con.setAutoCommit[false]; ResultSet rs = null; String priceQuery = "SELECT COF_NAME, PRICE FROM COFFEES " + "WHERE COF_NAME = ?"; String updateQuery = "UPDATE COFFEES SET PRICE = ? " + "WHERE COF_NAME = ?"; try [PreparedStatement getPrice = con.prepareStatement[priceQuery, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY]; PreparedStatement updatePrice = con.prepareStatement[updateQuery]] { Savepoint save1 = con.setSavepoint[]; getPrice.setString[1, coffeeName]; if [!getPrice.execute[]] { System.out.println["Could not find entry for coffee named " + coffeeName]; } else { rs = getPrice.getResultSet[]; rs.first[]; float oldPrice = rs.getFloat["PRICE"]; float newPrice = oldPrice + [oldPrice * priceModifier]; System.out.printf["Old price of %s is $%.2f%n", coffeeName, oldPrice]; System.out.printf["New price of %s is $%.2f%n", coffeeName, newPrice]; System.out.println["Performing update..."]; updatePrice.setFloat[1, newPrice]; updatePrice.setString[2, coffeeName]; updatePrice.executeUpdate[]; System.out.println["\nCOFFEES table after update:"]; CoffeesTable.viewTable[con]; if [newPrice > maximumPrice] { System.out.printf["The new price, $%.2f, is greater " + "than the maximum price, $%.2f. " + "Rolling back the transaction...%n", newPrice, maximumPrice]; con.rollback[save1]; System.out.println["\nCOFFEES table after rollback:"]; CoffeesTable.viewTable[con]; } con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; } finally { con.setAutoCommit[true]; } }2 nhưng lại trì hoãn việc nhập đó trong vài ngày. Trong khi đó, giá tăng và hôm nay chủ sở hữu đang trong quá trình nhập giá cao hơn. Nhân viên cuối cùng cũng xoay sở để nhập các mức giá hiện đã lỗi thời vào cùng thời điểm mà chủ sở hữu đang cố gắng cập nhật bảng. Sau khi chèn giá lỗi thời, nhân viên nhận ra rằng chúng không còn hiệu lực và gọi phương thức
public void modifyPricesByPercentage[ String coffeeName, float priceModifier, float maximumPrice] throws SQLException { con.setAutoCommit[false]; ResultSet rs = null; String priceQuery = "SELECT COF_NAME, PRICE FROM COFFEES " + "WHERE COF_NAME = ?"; String updateQuery = "UPDATE COFFEES SET PRICE = ? " + "WHERE COF_NAME = ?"; try [PreparedStatement getPrice = con.prepareStatement[priceQuery, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY]; PreparedStatement updatePrice = con.prepareStatement[updateQuery]] { Savepoint save1 = con.setSavepoint[]; getPrice.setString[1, coffeeName]; if [!getPrice.execute[]] { System.out.println["Could not find entry for coffee named " + coffeeName]; } else { rs = getPrice.getResultSet[]; rs.first[]; float oldPrice = rs.getFloat["PRICE"]; float newPrice = oldPrice + [oldPrice * priceModifier]; System.out.printf["Old price of %s is $%.2f%n", coffeeName, oldPrice]; System.out.printf["New price of %s is $%.2f%n", coffeeName, newPrice]; System.out.println["Performing update..."]; updatePrice.setFloat[1, newPrice]; updatePrice.setString[2, coffeeName]; updatePrice.executeUpdate[]; System.out.println["\nCOFFEES table after update:"]; CoffeesTable.viewTable[con]; if [newPrice > maximumPrice] { System.out.printf["The new price, $%.2f, is greater " + "than the maximum price, $%.2f. " + "Rolling back the transaction...%n", newPrice, maximumPrice]; con.rollback[save1]; System.out.println["\nCOFFEES table after rollback:"]; CoffeesTable.viewTable[con]; } con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; } finally { con.setAutoCommit[true]; } }3
public void modifyPricesByPercentage[ String coffeeName, float priceModifier, float maximumPrice] throws SQLException { con.setAutoCommit[false]; ResultSet rs = null; String priceQuery = "SELECT COF_NAME, PRICE FROM COFFEES " + "WHERE COF_NAME = ?"; String updateQuery = "UPDATE COFFEES SET PRICE = ? " + "WHERE COF_NAME = ?"; try [PreparedStatement getPrice = con.prepareStatement[priceQuery, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY]; PreparedStatement updatePrice = con.prepareStatement[updateQuery]] { Savepoint save1 = con.setSavepoint[]; getPrice.setString[1, coffeeName]; if [!getPrice.execute[]] { System.out.println["Could not find entry for coffee named " + coffeeName]; } else { rs = getPrice.getResultSet[]; rs.first[]; float oldPrice = rs.getFloat["PRICE"]; float newPrice = oldPrice + [oldPrice * priceModifier]; System.out.printf["Old price of %s is $%.2f%n", coffeeName, oldPrice]; System.out.printf["New price of %s is $%.2f%n", coffeeName, newPrice]; System.out.println["Performing update..."]; updatePrice.setFloat[1, newPrice]; updatePrice.setString[2, coffeeName]; updatePrice.executeUpdate[]; System.out.println["\nCOFFEES table after update:"]; CoffeesTable.viewTable[con]; if [newPrice > maximumPrice] { System.out.printf["The new price, $%.2f, is greater " + "than the maximum price, $%.2f. " + "Rolling back the transaction...%n", newPrice, maximumPrice]; con.rollback[save1]; System.out.println["\nCOFFEES table after rollback:"]; CoffeesTable.viewTable[con]; } con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; } finally { con.setAutoCommit[true]; } }4 để hoàn tác tác dụng của chúng. [Phương pháp
public void modifyPricesByPercentage[ String coffeeName, float priceModifier, float maximumPrice] throws SQLException { con.setAutoCommit[false]; ResultSet rs = null; String priceQuery = "SELECT COF_NAME, PRICE FROM COFFEES " + "WHERE COF_NAME = ?"; String updateQuery = "UPDATE COFFEES SET PRICE = ? " + "WHERE COF_NAME = ?"; try [PreparedStatement getPrice = con.prepareStatement[priceQuery, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY]; PreparedStatement updatePrice = con.prepareStatement[updateQuery]] { Savepoint save1 = con.setSavepoint[]; getPrice.setString[1, coffeeName]; if [!getPrice.execute[]] { System.out.println["Could not find entry for coffee named " + coffeeName]; } else { rs = getPrice.getResultSet[]; rs.first[]; float oldPrice = rs.getFloat["PRICE"]; float newPrice = oldPrice + [oldPrice * priceModifier]; System.out.printf["Old price of %s is $%.2f%n", coffeeName, oldPrice]; System.out.printf["New price of %s is $%.2f%n", coffeeName, newPrice]; System.out.println["Performing update..."]; updatePrice.setFloat[1, newPrice]; updatePrice.setString[2, coffeeName]; updatePrice.executeUpdate[]; System.out.println["\nCOFFEES table after update:"]; CoffeesTable.viewTable[con]; if [newPrice > maximumPrice] { System.out.printf["The new price, $%.2f, is greater " + "than the maximum price, $%.2f. " + "Rolling back the transaction...%n", newPrice, maximumPrice]; con.rollback[save1]; System.out.println["\nCOFFEES table after rollback:"]; CoffeesTable.viewTable[con]; } con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; } finally { con.setAutoCommit[true]; } }4 hủy bỏ một giao dịch và khôi phục các giá trị về giá trị ban đầu trước khi cố gắng cập nhật. ] Đồng thời, chủ sở hữu đang thực hiện câu lệnh
public void modifyPricesByPercentage[ String coffeeName, float priceModifier, float maximumPrice] throws SQLException { con.setAutoCommit[false]; ResultSet rs = null; String priceQuery = "SELECT COF_NAME, PRICE FROM COFFEES " + "WHERE COF_NAME = ?"; String updateQuery = "UPDATE COFFEES SET PRICE = ? " + "WHERE COF_NAME = ?"; try [PreparedStatement getPrice = con.prepareStatement[priceQuery, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY]; PreparedStatement updatePrice = con.prepareStatement[updateQuery]] { Savepoint save1 = con.setSavepoint[]; getPrice.setString[1, coffeeName]; if [!getPrice.execute[]] { System.out.println["Could not find entry for coffee named " + coffeeName]; } else { rs = getPrice.getResultSet[]; rs.first[]; float oldPrice = rs.getFloat["PRICE"]; float newPrice = oldPrice + [oldPrice * priceModifier]; System.out.printf["Old price of %s is $%.2f%n", coffeeName, oldPrice]; System.out.printf["New price of %s is $%.2f%n", coffeeName, newPrice]; System.out.println["Performing update..."]; updatePrice.setFloat[1, newPrice]; updatePrice.setString[2, coffeeName]; updatePrice.executeUpdate[]; System.out.println["\nCOFFEES table after update:"]; CoffeesTable.viewTable[con]; if [newPrice > maximumPrice] { System.out.printf["The new price, $%.2f, is greater " + "than the maximum price, $%.2f. " + "Rolling back the transaction...%n", newPrice, maximumPrice]; con.rollback[save1]; System.out.println["\nCOFFEES table after rollback:"]; CoffeesTable.viewTable[con]; } con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; } finally { con.setAutoCommit[true]; } }6 và in giá mới. Trong trường hợp này, có thể chủ sở hữu in giá đã bị lùi về giá trị trước đó khiến giá in không chính xác
Loại tình huống này có thể tránh được bằng cách sử dụng các giao dịch, cung cấp một số mức độ bảo vệ chống lại các xung đột phát sinh khi hai người dùng truy cập dữ liệu cùng một lúc
Để tránh xung đột trong quá trình giao dịch, DBMS sử dụng khóa, cơ chế chặn quyền truy cập của người khác vào dữ liệu đang được giao dịch truy cập. [Lưu ý rằng trong chế độ tự động cam kết, trong đó mỗi câu lệnh là một giao dịch, các khóa chỉ được giữ cho một câu lệnh. ] Sau khi khóa được đặt, nó vẫn có hiệu lực cho đến khi giao dịch được thực hiện hoặc khôi phục. Ví dụ: một DBMS có thể khóa một hàng của bảng cho đến khi các bản cập nhật cho nó được thực hiện. Tác dụng của khóa này là ngăn người dùng đọc bẩn, nghĩa là đọc một giá trị trước khi nó được thực hiện vĩnh viễn. [Truy cập một giá trị cập nhật chưa được cam kết được coi là đọc bẩn vì giá trị đó có thể được khôi phục về giá trị trước đó. Nếu bạn đọc một giá trị mà sau đó được khôi phục, bạn sẽ đọc một giá trị không hợp lệ. ]
Cách khóa được thiết lập được xác định bởi cái được gọi là mức cô lập giao dịch, có thể bao gồm từ hoàn toàn không hỗ trợ giao dịch đến hỗ trợ các giao dịch thực thi các quy tắc truy cập rất nghiêm ngặt
Một ví dụ về mức cô lập giao dịch là
public void modifyPricesByPercentage[ String coffeeName, float priceModifier, float maximumPrice] throws SQLException { con.setAutoCommit[false]; ResultSet rs = null; String priceQuery = "SELECT COF_NAME, PRICE FROM COFFEES " + "WHERE COF_NAME = ?"; String updateQuery = "UPDATE COFFEES SET PRICE = ? " + "WHERE COF_NAME = ?"; try [PreparedStatement getPrice = con.prepareStatement[priceQuery, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY]; PreparedStatement updatePrice = con.prepareStatement[updateQuery]] { Savepoint save1 = con.setSavepoint[]; getPrice.setString[1, coffeeName]; if [!getPrice.execute[]] { System.out.println["Could not find entry for coffee named " + coffeeName]; } else { rs = getPrice.getResultSet[]; rs.first[]; float oldPrice = rs.getFloat["PRICE"]; float newPrice = oldPrice + [oldPrice * priceModifier]; System.out.printf["Old price of %s is $%.2f%n", coffeeName, oldPrice]; System.out.printf["New price of %s is $%.2f%n", coffeeName, newPrice]; System.out.println["Performing update..."]; updatePrice.setFloat[1, newPrice]; updatePrice.setString[2, coffeeName]; updatePrice.executeUpdate[]; System.out.println["\nCOFFEES table after update:"]; CoffeesTable.viewTable[con]; if [newPrice > maximumPrice] { System.out.printf["The new price, $%.2f, is greater " + "than the maximum price, $%.2f. " + "Rolling back the transaction...%n", newPrice, maximumPrice]; con.rollback[save1]; System.out.println["\nCOFFEES table after rollback:"]; CoffeesTable.viewTable[con]; } con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; } finally { con.setAutoCommit[true]; } }7, mức này sẽ không cho phép truy cập một giá trị cho đến sau khi nó được cam kết. Nói cách khác, nếu mức cô lập giao dịch được đặt thành
public void modifyPricesByPercentage[ String coffeeName, float priceModifier, float maximumPrice] throws SQLException { con.setAutoCommit[false]; ResultSet rs = null; String priceQuery = "SELECT COF_NAME, PRICE FROM COFFEES " + "WHERE COF_NAME = ?"; String updateQuery = "UPDATE COFFEES SET PRICE = ? " + "WHERE COF_NAME = ?"; try [PreparedStatement getPrice = con.prepareStatement[priceQuery, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY]; PreparedStatement updatePrice = con.prepareStatement[updateQuery]] { Savepoint save1 = con.setSavepoint[]; getPrice.setString[1, coffeeName]; if [!getPrice.execute[]] { System.out.println["Could not find entry for coffee named " + coffeeName]; } else { rs = getPrice.getResultSet[]; rs.first[]; float oldPrice = rs.getFloat["PRICE"]; float newPrice = oldPrice + [oldPrice * priceModifier]; System.out.printf["Old price of %s is $%.2f%n", coffeeName, oldPrice]; System.out.printf["New price of %s is $%.2f%n", coffeeName, newPrice]; System.out.println["Performing update..."]; updatePrice.setFloat[1, newPrice]; updatePrice.setString[2, coffeeName]; updatePrice.executeUpdate[]; System.out.println["\nCOFFEES table after update:"]; CoffeesTable.viewTable[con]; if [newPrice > maximumPrice] { System.out.printf["The new price, $%.2f, is greater " + "than the maximum price, $%.2f. " + "Rolling back the transaction...%n", newPrice, maximumPrice]; con.rollback[save1]; System.out.println["\nCOFFEES table after rollback:"]; CoffeesTable.viewTable[con]; } con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; } finally { con.setAutoCommit[true]; } }7, thì DBMS không cho phép đọc bẩn xảy ra. Giao diện
public void modifyPricesByPercentage[ String coffeeName, float priceModifier, float maximumPrice] throws SQLException { con.setAutoCommit[false]; ResultSet rs = null; String priceQuery = "SELECT COF_NAME, PRICE FROM COFFEES " + "WHERE COF_NAME = ?"; String updateQuery = "UPDATE COFFEES SET PRICE = ? " + "WHERE COF_NAME = ?"; try [PreparedStatement getPrice = con.prepareStatement[priceQuery, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY]; PreparedStatement updatePrice = con.prepareStatement[updateQuery]] { Savepoint save1 = con.setSavepoint[]; getPrice.setString[1, coffeeName]; if [!getPrice.execute[]] { System.out.println["Could not find entry for coffee named " + coffeeName]; } else { rs = getPrice.getResultSet[]; rs.first[]; float oldPrice = rs.getFloat["PRICE"]; float newPrice = oldPrice + [oldPrice * priceModifier]; System.out.printf["Old price of %s is $%.2f%n", coffeeName, oldPrice]; System.out.printf["New price of %s is $%.2f%n", coffeeName, newPrice]; System.out.println["Performing update..."]; updatePrice.setFloat[1, newPrice]; updatePrice.setString[2, coffeeName]; updatePrice.executeUpdate[]; System.out.println["\nCOFFEES table after update:"]; CoffeesTable.viewTable[con]; if [newPrice > maximumPrice] { System.out.printf["The new price, $%.2f, is greater " + "than the maximum price, $%.2f. " + "Rolling back the transaction...%n", newPrice, maximumPrice]; con.rollback[save1]; System.out.println["\nCOFFEES table after rollback:"]; CoffeesTable.viewTable[con]; } con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; } finally { con.setAutoCommit[true]; } }3 bao gồm năm giá trị đại diện cho các mức cô lập giao dịch mà bạn có thể sử dụng trong JDBCMức cô lập Giao dịch Đọc bẩn Đọc không lặp lại Đọc ảo_______180Không được hỗ trợKhông áp dụngKhông áp dụngKhông áp dụng
public void modifyPricesByPercentage[ String coffeeName, float priceModifier, float maximumPrice] throws SQLException { con.setAutoCommit[false]; ResultSet rs = null; String priceQuery = "SELECT COF_NAME, PRICE FROM COFFEES " + "WHERE COF_NAME = ?"; String updateQuery = "UPDATE COFFEES SET PRICE = ? " + "WHERE COF_NAME = ?"; try [PreparedStatement getPrice = con.prepareStatement[priceQuery, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY]; PreparedStatement updatePrice = con.prepareStatement[updateQuery]] { Savepoint save1 = con.setSavepoint[]; getPrice.setString[1, coffeeName]; if [!getPrice.execute[]] { System.out.println["Could not find entry for coffee named " + coffeeName]; } else { rs = getPrice.getResultSet[]; rs.first[]; float oldPrice = rs.getFloat["PRICE"]; float newPrice = oldPrice + [oldPrice * priceModifier]; System.out.printf["Old price of %s is $%.2f%n", coffeeName, oldPrice]; System.out.printf["New price of %s is $%.2f%n", coffeeName, newPrice]; System.out.println["Performing update..."]; updatePrice.setFloat[1, newPrice]; updatePrice.setString[2, coffeeName]; updatePrice.executeUpdate[]; System.out.println["\nCOFFEES table after update:"]; CoffeesTable.viewTable[con]; if [newPrice > maximumPrice] { System.out.printf["The new price, $%.2f, is greater " + "than the maximum price, $%.2f. " + "Rolling back the transaction...%n", newPrice, maximumPrice]; con.rollback[save1]; System.out.println["\nCOFFEES table after rollback:"]; CoffeesTable.viewTable[con]; } con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; } finally { con.setAutoCommit[true]; } }7Được hỗ trợNgăn chặnCho phépCho phép
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }82Được hỗ trợCho phépCho phépCho phépCho phép
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }83Được hỗ trợNgăn chặnĐã ngăn chặnĐược phép
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }84Được hỗ trợNgăn chặnĐã ngăn chặnĐã ngăn chặn
Việc đọc không thể lặp lại xảy ra khi giao dịch A truy xuất một hàng, giao dịch B sau đó cập nhật hàng đó và giao dịch A sau đó truy xuất lại cùng một hàng. Giao dịch A truy xuất cùng một hàng hai lần nhưng thấy dữ liệu khác nhau
Đọc ảo xảy ra khi giao dịch A truy xuất một tập hợp các hàng thỏa mãn một điều kiện nhất định, giao dịch B sau đó chèn hoặc cập nhật một hàng sao cho hàng hiện đáp ứng điều kiện trong giao dịch A và giao dịch A sau đó lặp lại truy xuất có điều kiện. Giao dịch A hiện thấy một hàng bổ sung. Hàng này được gọi là phantom
Thông thường, bạn không cần phải làm bất cứ điều gì về mức cô lập giao dịch; . Mức cô lập giao dịch mặc định phụ thuộc vào DBMS của bạn. Ví dụ: đối với Java DB, nó là
public void modifyPricesByPercentage[ String coffeeName, float priceModifier, float maximumPrice] throws SQLException { con.setAutoCommit[false]; ResultSet rs = null; String priceQuery = "SELECT COF_NAME, PRICE FROM COFFEES " + "WHERE COF_NAME = ?"; String updateQuery = "UPDATE COFFEES SET PRICE = ? " + "WHERE COF_NAME = ?"; try [PreparedStatement getPrice = con.prepareStatement[priceQuery, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY]; PreparedStatement updatePrice = con.prepareStatement[updateQuery]] { Savepoint save1 = con.setSavepoint[]; getPrice.setString[1, coffeeName]; if [!getPrice.execute[]] { System.out.println["Could not find entry for coffee named " + coffeeName]; } else { rs = getPrice.getResultSet[]; rs.first[]; float oldPrice = rs.getFloat["PRICE"]; float newPrice = oldPrice + [oldPrice * priceModifier]; System.out.printf["Old price of %s is $%.2f%n", coffeeName, oldPrice]; System.out.printf["New price of %s is $%.2f%n", coffeeName, newPrice]; System.out.println["Performing update..."]; updatePrice.setFloat[1, newPrice]; updatePrice.setString[2, coffeeName]; updatePrice.executeUpdate[]; System.out.println["\nCOFFEES table after update:"]; CoffeesTable.viewTable[con]; if [newPrice > maximumPrice] { System.out.printf["The new price, $%.2f, is greater " + "than the maximum price, $%.2f. " + "Rolling back the transaction...%n", newPrice, maximumPrice]; con.rollback[save1]; System.out.println["\nCOFFEES table after rollback:"]; CoffeesTable.viewTable[con]; } con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; } finally { con.setAutoCommit[true]; } }7. JDBC cho phép bạn tìm hiểu DBMS của bạn được đặt ở mức cô lập giao dịch nào [sử dụng phương pháp
public void modifyPricesByPercentage[ String coffeeName, float priceModifier, float maximumPrice] throws SQLException { con.setAutoCommit[false]; ResultSet rs = null; String priceQuery = "SELECT COF_NAME, PRICE FROM COFFEES " + "WHERE COF_NAME = ?"; String updateQuery = "UPDATE COFFEES SET PRICE = ? " + "WHERE COF_NAME = ?"; try [PreparedStatement getPrice = con.prepareStatement[priceQuery, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY]; PreparedStatement updatePrice = con.prepareStatement[updateQuery]] { Savepoint save1 = con.setSavepoint[]; getPrice.setString[1, coffeeName]; if [!getPrice.execute[]] { System.out.println["Could not find entry for coffee named " + coffeeName]; } else { rs = getPrice.getResultSet[]; rs.first[]; float oldPrice = rs.getFloat["PRICE"]; float newPrice = oldPrice + [oldPrice * priceModifier]; System.out.printf["Old price of %s is $%.2f%n", coffeeName, oldPrice]; System.out.printf["New price of %s is $%.2f%n", coffeeName, newPrice]; System.out.println["Performing update..."]; updatePrice.setFloat[1, newPrice]; updatePrice.setString[2, coffeeName]; updatePrice.executeUpdate[]; System.out.println["\nCOFFEES table after update:"]; CoffeesTable.viewTable[con]; if [newPrice > maximumPrice] { System.out.printf["The new price, $%.2f, is greater " + "than the maximum price, $%.2f. " + "Rolling back the transaction...%n", newPrice, maximumPrice]; con.rollback[save1]; System.out.println["\nCOFFEES table after rollback:"]; CoffeesTable.viewTable[con]; } con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; } finally { con.setAutoCommit[true]; } }3
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }87] và cũng cho phép bạn đặt nó ở một mức khác [sử dụng phương pháp
public void modifyPricesByPercentage[ String coffeeName, float priceModifier, float maximumPrice] throws SQLException { con.setAutoCommit[false]; ResultSet rs = null; String priceQuery = "SELECT COF_NAME, PRICE FROM COFFEES " + "WHERE COF_NAME = ?"; String updateQuery = "UPDATE COFFEES SET PRICE = ? " + "WHERE COF_NAME = ?"; try [PreparedStatement getPrice = con.prepareStatement[priceQuery, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY]; PreparedStatement updatePrice = con.prepareStatement[updateQuery]] { Savepoint save1 = con.setSavepoint[]; getPrice.setString[1, coffeeName]; if [!getPrice.execute[]] { System.out.println["Could not find entry for coffee named " + coffeeName]; } else { rs = getPrice.getResultSet[]; rs.first[]; float oldPrice = rs.getFloat["PRICE"]; float newPrice = oldPrice + [oldPrice * priceModifier]; System.out.printf["Old price of %s is $%.2f%n", coffeeName, oldPrice]; System.out.printf["New price of %s is $%.2f%n", coffeeName, newPrice]; System.out.println["Performing update..."]; updatePrice.setFloat[1, newPrice]; updatePrice.setString[2, coffeeName]; updatePrice.executeUpdate[]; System.out.println["\nCOFFEES table after update:"]; CoffeesTable.viewTable[con]; if [newPrice > maximumPrice] { System.out.printf["The new price, $%.2f, is greater " + "than the maximum price, $%.2f. " + "Rolling back the transaction...%n", newPrice, maximumPrice]; con.rollback[save1]; System.out.println["\nCOFFEES table after rollback:"]; CoffeesTable.viewTable[con]; } con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; } finally { con.setAutoCommit[true]; } }3
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }89]
Ghi chú. Trình điều khiển JDBC có thể không hỗ trợ tất cả các mức cô lập giao dịch. Nếu trình điều khiển không hỗ trợ mức cô lập được chỉ định trong lệnh gọi của
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }89, trình điều khiển có thể thay thế mức cô lập giao dịch cao hơn, hạn chế hơn. Nếu trình điều khiển không thể thay thế mức giao dịch cao hơn, nó sẽ ném một
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }91. Sử dụng phương pháp
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }92 để xác định xem trình điều khiển có hỗ trợ một mức nhất định hay không
Phương thức
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }93, đặt một đối tượng
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }94 trong giao dịch hiện tại. Phương thức
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }95 bị quá tải để lấy đối số
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }94
Phương pháp sau đây,
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }97, tăng giá của một loại cà phê cụ thể theo tỷ lệ phần trăm,
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }98. Tuy nhiên, nếu giá mới lớn hơn giá đã chỉ định,
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }99, thì giá sẽ được hoàn nguyên về giá ban đầu
public void modifyPricesByPercentage[ String coffeeName, float priceModifier, float maximumPrice] throws SQLException { con.setAutoCommit[false]; ResultSet rs = null; String priceQuery = "SELECT COF_NAME, PRICE FROM COFFEES " + "WHERE COF_NAME = ?"; String updateQuery = "UPDATE COFFEES SET PRICE = ? " + "WHERE COF_NAME = ?"; try [PreparedStatement getPrice = con.prepareStatement[priceQuery, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY]; PreparedStatement updatePrice = con.prepareStatement[updateQuery]] { Savepoint save1 = con.setSavepoint[]; getPrice.setString[1, coffeeName]; if [!getPrice.execute[]] { System.out.println["Could not find entry for coffee named " + coffeeName]; } else { rs = getPrice.getResultSet[]; rs.first[]; float oldPrice = rs.getFloat["PRICE"]; float newPrice = oldPrice + [oldPrice * priceModifier]; System.out.printf["Old price of %s is $%.2f%n", coffeeName, oldPrice]; System.out.printf["New price of %s is $%.2f%n", coffeeName, newPrice]; System.out.println["Performing update..."]; updatePrice.setFloat[1, newPrice]; updatePrice.setString[2, coffeeName]; updatePrice.executeUpdate[]; System.out.println["\nCOFFEES table after update:"]; CoffeesTable.viewTable[con]; if [newPrice > maximumPrice] { System.out.printf["The new price, $%.2f, is greater " + "than the maximum price, $%.2f. " + "Rolling back the transaction...%n", newPrice, maximumPrice]; con.rollback[save1]; System.out.println["\nCOFFEES table after rollback:"]; CoffeesTable.viewTable[con]; } con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; } finally { con.setAutoCommit[true]; } }
Câu lệnh sau chỉ định rằng con trỏ của đối tượng
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }30 được tạo từ truy vấn
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }31 được đóng khi phương thức
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }4 được gọi. Lưu ý rằng nếu DBM của bạn không hỗ trợ
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }33 thì hằng số này sẽ bị bỏ qua
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }8
Phương thức bắt đầu bằng cách tạo một
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }94 với câu lệnh sau
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }9
Phương thức kiểm tra xem giá mới có lớn hơn giá trị
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }99 không. Nếu vậy, phương thức khôi phục giao dịch với câu lệnh sau
Do đó, khi phương thức thực hiện giao dịch bằng cách gọi phương thức
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }36, nó sẽ không thực hiện bất kỳ hàng nào có liên kết với
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }94 đã được khôi phục;
Phương thức
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }38 lấy một đối tượng
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }94 làm tham số và xóa nó khỏi giao dịch hiện tại
Sau khi một điểm lưu trữ đã được giải phóng, việc cố gắng tham chiếu nó trong thao tác khôi phục sẽ khiến một
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }91 bị ném. Bất kỳ điểm lưu trữ nào đã được tạo trong giao dịch sẽ tự động được giải phóng và trở nên không hợp lệ khi giao dịch được thực hiện hoặc khi toàn bộ giao dịch được khôi phục. Việc đưa một giao dịch trở lại điểm lưu trữ sẽ tự động phát hành và làm mất hiệu lực bất kỳ điểm lưu trữ nào khác được tạo sau điểm lưu trữ được đề cập
Như đã đề cập trước đó, việc gọi phương thức
public void modifyPricesByPercentage[ String coffeeName, float priceModifier, float maximumPrice] throws SQLException { con.setAutoCommit[false]; ResultSet rs = null; String priceQuery = "SELECT COF_NAME, PRICE FROM COFFEES " + "WHERE COF_NAME = ?"; String updateQuery = "UPDATE COFFEES SET PRICE = ? " + "WHERE COF_NAME = ?"; try [PreparedStatement getPrice = con.prepareStatement[priceQuery, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY]; PreparedStatement updatePrice = con.prepareStatement[updateQuery]] { Savepoint save1 = con.setSavepoint[]; getPrice.setString[1, coffeeName]; if [!getPrice.execute[]] { System.out.println["Could not find entry for coffee named " + coffeeName]; } else { rs = getPrice.getResultSet[]; rs.first[]; float oldPrice = rs.getFloat["PRICE"]; float newPrice = oldPrice + [oldPrice * priceModifier]; System.out.printf["Old price of %s is $%.2f%n", coffeeName, oldPrice]; System.out.printf["New price of %s is $%.2f%n", coffeeName, newPrice]; System.out.println["Performing update..."]; updatePrice.setFloat[1, newPrice]; updatePrice.setString[2, coffeeName]; updatePrice.executeUpdate[]; System.out.println["\nCOFFEES table after update:"]; CoffeesTable.viewTable[con]; if [newPrice > maximumPrice] { System.out.printf["The new price, $%.2f, is greater " + "than the maximum price, $%.2f. " + "Rolling back the transaction...%n", newPrice, maximumPrice]; con.rollback[save1]; System.out.println["\nCOFFEES table after rollback:"]; CoffeesTable.viewTable[con]; } con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; } finally { con.setAutoCommit[true]; } }4 sẽ chấm dứt một giao dịch và trả về bất kỳ giá trị nào đã được sửa đổi thành giá trị trước đó của chúng. Nếu bạn đang cố gắng thực hiện một hoặc nhiều câu lệnh trong một giao dịch và nhận được một
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }91, hãy gọi phương thức
public void modifyPricesByPercentage[ String coffeeName, float priceModifier, float maximumPrice] throws SQLException { con.setAutoCommit[false]; ResultSet rs = null; String priceQuery = "SELECT COF_NAME, PRICE FROM COFFEES " + "WHERE COF_NAME = ?"; String updateQuery = "UPDATE COFFEES SET PRICE = ? " + "WHERE COF_NAME = ?"; try [PreparedStatement getPrice = con.prepareStatement[priceQuery, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY]; PreparedStatement updatePrice = con.prepareStatement[updateQuery]] { Savepoint save1 = con.setSavepoint[]; getPrice.setString[1, coffeeName]; if [!getPrice.execute[]] { System.out.println["Could not find entry for coffee named " + coffeeName]; } else { rs = getPrice.getResultSet[]; rs.first[]; float oldPrice = rs.getFloat["PRICE"]; float newPrice = oldPrice + [oldPrice * priceModifier]; System.out.printf["Old price of %s is $%.2f%n", coffeeName, oldPrice]; System.out.printf["New price of %s is $%.2f%n", coffeeName, newPrice]; System.out.println["Performing update..."]; updatePrice.setFloat[1, newPrice]; updatePrice.setString[2, coffeeName]; updatePrice.executeUpdate[]; System.out.println["\nCOFFEES table after update:"]; CoffeesTable.viewTable[con]; if [newPrice > maximumPrice] { System.out.printf["The new price, $%.2f, is greater " + "than the maximum price, $%.2f. " + "Rolling back the transaction...%n", newPrice, maximumPrice]; con.rollback[save1]; System.out.println["\nCOFFEES table after rollback:"]; CoffeesTable.viewTable[con]; } con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; } finally { con.setAutoCommit[true]; } }4 để kết thúc giao dịch và bắt đầu lại giao dịch. Đó là cách duy nhất để biết những gì đã được cam kết và những gì chưa được cam kết. Bắt một
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }91 cho bạn biết rằng có điều gì đó không ổn, nhưng nó không cho bạn biết điều gì đã hoặc chưa xảy ra. Bởi vì bạn không thể tin rằng không có gì được cam kết, gọi phương thức
public void modifyPricesByPercentage[ String coffeeName, float priceModifier, float maximumPrice] throws SQLException { con.setAutoCommit[false]; ResultSet rs = null; String priceQuery = "SELECT COF_NAME, PRICE FROM COFFEES " + "WHERE COF_NAME = ?"; String updateQuery = "UPDATE COFFEES SET PRICE = ? " + "WHERE COF_NAME = ?"; try [PreparedStatement getPrice = con.prepareStatement[priceQuery, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY]; PreparedStatement updatePrice = con.prepareStatement[updateQuery]] { Savepoint save1 = con.setSavepoint[]; getPrice.setString[1, coffeeName]; if [!getPrice.execute[]] { System.out.println["Could not find entry for coffee named " + coffeeName]; } else { rs = getPrice.getResultSet[]; rs.first[]; float oldPrice = rs.getFloat["PRICE"]; float newPrice = oldPrice + [oldPrice * priceModifier]; System.out.printf["Old price of %s is $%.2f%n", coffeeName, oldPrice]; System.out.printf["New price of %s is $%.2f%n", coffeeName, newPrice]; System.out.println["Performing update..."]; updatePrice.setFloat[1, newPrice]; updatePrice.setString[2, coffeeName]; updatePrice.executeUpdate[]; System.out.println["\nCOFFEES table after update:"]; CoffeesTable.viewTable[con]; if [newPrice > maximumPrice] { System.out.printf["The new price, $%.2f, is greater " + "than the maximum price, $%.2f. " + "Rolling back the transaction...%n", newPrice, maximumPrice]; con.rollback[save1]; System.out.println["\nCOFFEES table after rollback:"]; CoffeesTable.viewTable[con]; } con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; } finally { con.setAutoCommit[true]; } }4 là cách duy nhất để chắc chắn
Phương thức
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }6 thể hiện một giao dịch và bao gồm một khối
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }47 gọi phương thức
public void modifyPricesByPercentage[ String coffeeName, float priceModifier, float maximumPrice] throws SQLException { con.setAutoCommit[false]; ResultSet rs = null; String priceQuery = "SELECT COF_NAME, PRICE FROM COFFEES " + "WHERE COF_NAME = ?"; String updateQuery = "UPDATE COFFEES SET PRICE = ? " + "WHERE COF_NAME = ?"; try [PreparedStatement getPrice = con.prepareStatement[priceQuery, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY]; PreparedStatement updatePrice = con.prepareStatement[updateQuery]] { Savepoint save1 = con.setSavepoint[]; getPrice.setString[1, coffeeName]; if [!getPrice.execute[]] { System.out.println["Could not find entry for coffee named " + coffeeName]; } else { rs = getPrice.getResultSet[]; rs.first[]; float oldPrice = rs.getFloat["PRICE"]; float newPrice = oldPrice + [oldPrice * priceModifier]; System.out.printf["Old price of %s is $%.2f%n", coffeeName, oldPrice]; System.out.printf["New price of %s is $%.2f%n", coffeeName, newPrice]; System.out.println["Performing update..."]; updatePrice.setFloat[1, newPrice]; updatePrice.setString[2, coffeeName]; updatePrice.executeUpdate[]; System.out.println["\nCOFFEES table after update:"]; CoffeesTable.viewTable[con]; if [newPrice > maximumPrice] { System.out.printf["The new price, $%.2f, is greater " + "than the maximum price, $%.2f. " + "Rolling back the transaction...%n", newPrice, maximumPrice]; con.rollback[save1]; System.out.println["\nCOFFEES table after rollback:"]; CoffeesTable.viewTable[con]; } con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; } finally { con.setAutoCommit[true]; } }4. Nếu ứng dụng tiếp tục và sử dụng kết quả của giao dịch, lệnh gọi phương thức
public void modifyPricesByPercentage[ String coffeeName, float priceModifier, float maximumPrice] throws SQLException { con.setAutoCommit[false]; ResultSet rs = null; String priceQuery = "SELECT COF_NAME, PRICE FROM COFFEES " + "WHERE COF_NAME = ?"; String updateQuery = "UPDATE COFFEES SET PRICE = ? " + "WHERE COF_NAME = ?"; try [PreparedStatement getPrice = con.prepareStatement[priceQuery, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY]; PreparedStatement updatePrice = con.prepareStatement[updateQuery]] { Savepoint save1 = con.setSavepoint[]; getPrice.setString[1, coffeeName]; if [!getPrice.execute[]] { System.out.println["Could not find entry for coffee named " + coffeeName]; } else { rs = getPrice.getResultSet[]; rs.first[]; float oldPrice = rs.getFloat["PRICE"]; float newPrice = oldPrice + [oldPrice * priceModifier]; System.out.printf["Old price of %s is $%.2f%n", coffeeName, oldPrice]; System.out.printf["New price of %s is $%.2f%n", coffeeName, newPrice]; System.out.println["Performing update..."]; updatePrice.setFloat[1, newPrice]; updatePrice.setString[2, coffeeName]; updatePrice.executeUpdate[]; System.out.println["\nCOFFEES table after update:"]; CoffeesTable.viewTable[con]; if [newPrice > maximumPrice] { System.out.printf["The new price, $%.2f, is greater " + "than the maximum price, $%.2f. " + "Rolling back the transaction...%n", newPrice, maximumPrice]; con.rollback[save1]; System.out.println["\nCOFFEES table after rollback:"]; CoffeesTable.viewTable[con]; } con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; } finally { con.setAutoCommit[true]; } }4 trong khối
public void updateCoffeeSales[HashMap salesForWeek] throws SQLException { String updateString = "update COFFEES set SALES = ? where COF_NAME = ?"; String updateStatement = "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?"; try [PreparedStatement updateSales = con.prepareStatement[updateString]; PreparedStatement updateTotal = con.prepareStatement[updateStatement]] { con.setAutoCommit[false]; for [Map.Entry e : salesForWeek.entrySet[]] { updateSales.setInt[1, e.getValue[].intValue[]]; updateSales.setString[2, e.getKey[]]; updateSales.executeUpdate[]; updateTotal.setInt[1, e.getValue[].intValue[]]; updateTotal.setString[2, e.getKey[]]; updateTotal.executeUpdate[]; con.commit[]; } } catch [SQLException e] { JDBCTutorialUtilities.printSQLException[e]; if [con != null] { try { System.err.print["Transaction is being rolled back"]; con.rollback[]; } catch [SQLException excep] { JDBCTutorialUtilities.printSQLException[excep]; } } } }47 này sẽ ngăn việc sử dụng dữ liệu có thể không chính xác