我正在使用Azure SQL数据仓库中的JDBC尝试事务。事务已成功处理,但在事务之后,DDL命令失败并显示错误Operation cannot be performed within a transaction
。
这是我想要做的事情。
connection.createStatement().execute("CREATE TABLE " + schema + ".transaction_table (id INT)");
connection.createStatement().execute("INSERT INTO " + schema + ".transaction_table (id) VALUES (1)");
connection.createStatement().execute("INSERT INTO " + schema + ".transaction_table (id) VALUES (2)");
// Transaction starts
connection.setAutoCommit(false);
connection.createStatement().execute("DELETE FROM " + schema + ".transaction_table WHERE id = 2");
connection.createStatement().execute("INSERT INTO " + schema + ".transaction_table (id) VALUES (10)");
connection.commit();
connection.setAutoCommit(true);
// Transaction ends
// Next DDL command to succeed, but it does not
connectiom.createStatement().execute("CREATE TABLE " + schema + ".transaction_table_new (id INT)");
// Fails with `Operation cannot be performed within a transaction`
那么,我们如何在Azure SQL数据仓库中关闭事务。
我试着这样做。
try {
// This fails
connection.createStatement().execute("CREATE TABLE " + schema + ".transaction_table_new (id INT)");
} catch (SQLServerException e) {
if (e.getMessage().contains("Operation cannot be performed within a transaction")) {
// This succeeds
// Somehow the transaction was closed, may be because of the exception
connection.createStatement().execute("CREATE TABLE " + schema + ".transaction_table_new "(id INT)");
}
}
答案 0 :(得分:1)
SQL数据仓库期望CREATE TABLE语句在事务之外运行。通过将connection.setAutoCommit
设置为true,您将强制Java在事务中运行执行。我在Java上有点弱(已经有一段时间了)但你应该能够通过简单地注释掉setAutoCommit(true)
行来运行第二个DDL语句。这将使JDBC驱动程序仅处于执行模式,而不会在事务中运行execute()
操作。
答案 1 :(得分:1)
看起来我们必须手动结束交易。
看起来像这样
connection.setAutoCommit(false);
// Transaction statement 1
// Transaction statement 2
connection.commit();
connection.setAutoCommit(true);
connection.createStatement().execute("IF @@TRANCOUNT > 0 COMMIT TRAN");
这是因为,对于Azure SQL数据仓库,jdbc connection.commit()似乎并不总是发出COMMIT。它跟踪它正在管理的交易,并决定对其发送的内容“聪明”。因此,执行手动COMMIT TRAN以在执行任何DDL命令之前关闭所有打开的事务。
这很奇怪,因为我们不必为其他仓库或数据库执行此操作,但它可以正常工作。而且,这没有记录。