由于无效数据,有时执行诸如插入,更新或删除之类的数据库操作命令可能会引发异常。为了保护我们的应用程序数据的完整性,我们必须确保在事务失败时必须回退所有已执行的命令,以便它影响数据的状态。
在此示例中,我们使用MySQL数据库。要在MySQL中启用事务处理功能,请确保您使用的是InnoDB存储引擎来创建表。package org.nhooo.example.jdbc;
import java.sql.*;
public class TransactionRollbackExample {
private static final String URL = "jdbc:mysql://localhost/nhooo";
private static final String USERNAME = "root";
private static final String PASSWORD = "";
public static void main(String[] args) throws Exception {
try (Connection conn =
DriverManager.getConnection(URL, USERNAME, PASSWORD)) {
conn.setAutoCommit(false);
String query = "INSERT INTO orders (username, order_date) " +
"VALUES (?, ?)";
try (PreparedStatement stmt = conn.prepareStatement(query,
PreparedStatement.RETURN_GENERATED_KEYS)) {
stmt.setString(1, "javaduke");
stmt.setDate(2, new Date(System.currentTimeMillis()));
stmt.execute();
ResultSet keys = stmt.getGeneratedKeys();
int orderId = 1;
if (keys.next()) {
orderId = keys.getInt(1);
}
// 这是一条无效的语句,将导致
// 演示回滚。
query = "INSERT INTO order_details (order_id, product_id, " +
"quantity, price) VALUES (?, ?, ?, ?, ?)";
PreparedStatement detailStmt = conn.prepareStatement(query);
detailStmt.setInt(1, orderId);
detailStmt.setInt(2, 1);
detailStmt.setInt(3, 10);
detailStmt.setDouble(4, 29.99);
detailStmt.execute();
// 提交事务以将其标记为成功数据库操作
conn.commit();
System.out.println("Transaction commit...");
} catch (SQLException e) {
// 由于发生异常而回滚任何数据库事务
conn.rollback();
System.out.println("Transaction rollback...");
e.printStackTrace();
}
}
}
}
Maven依赖
mysql
mysql-connector-java
8.0.17