我有一个示例代码,它创建一个表,在其中插入一些行,然后尝试取消整个事务,但是 conn.rollback()
似乎只对 INSERT 语句有效,而CREATE TABLE 保持不受影响:新创建的表在数据库中保持永久不变,其中没有插入任何行。
这是将 JDBC 驱动程序与 MySQL DBMS 一起使用时的标准行为吗?
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class TestBatch {
public static void main(String[] args) {
try (Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/testdb?serverTimezone=UTC",
"root", "root")) {
// drop table
try (Statement dropStatement = conn.createStatement()) {
dropStatement.executeUpdate("DROP TABLE IF EXISTS mytable");
}
// create table, insert rows and rollback
conn.setAutoCommit(false);
try (Statement stmt = conn.createStatement()) {
stmt.addBatch("CREATE TABLE mytable (id INT)");
stmt.addBatch("INSERT INTO mytable VALUES (1)");
stmt.addBatch("INSERT INTO mytable VALUES (2)");
stmt.executeBatch();
conn.rollback();
} finally {
conn.setAutoCommit(true);
}
} catch (SQLException e) {
System.err.println(e.getMessage());
}
}
}
请注意,我使用的是带有 Connector/J 版本的 MySQL Server 8.0。 8.0.17,参数 default-storage-engine(在 C:\ProgramData\MySQL\MySQL Server 8.0\my.ini 中)也设置为 INNODB。 p>
最佳答案
正如 Paul Spiegel 和 Arnaud 所说,DDL 语句不能在 MySQL 中回滚。即使对于 MySQL 8 也是如此:https://dev.mysql.com/doc/refman/8.0/en/implicit-commit.html
无论好坏,DDL 语句都会提交任何挂起的事务,如果它们是本地的并且不能在 XA 事务中使用(因为这会导致一个参与者在事务协调器没有发出这样做的命令的情况下提交数据)。
关于java - 如何在使用 JDBC 驱动程序和 MySQL DBMS 时回滚 CREATE TABLE 和 DROP TABLE 等 DDL 语句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57553011/