gpt4 book ai didi

java - 将多个查询作为一个 dblink 事务执行

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:15:07 25 4
gpt4 key购买 nike

我在一个 Java 应用程序中工作,我需要同时执行这两个查询(作为 Java 中的字符串)并在出现错误时回滚事务。

SELECT dblink_exec('hostaddr=xxx.xx.xxx.xxx port=5432 dbname=bdname user=myuser password=mypass connect_timeout=2',
'INSERT INTO table3(field4)
VALUES (5)') AS result;

SELECT dblink_exec('hostaddr=xxx.xx.xxx.xxx port=5432 dbname=bdname user=myuser password=mypass connect_timeout=2',
'UPDATE table1 SET field2 = field2 + 3.0 WHERE field1 = 16436') AS result;

更新

我创建了一个字符串,两个查询用 ; 分隔,如评论中建议的那样

更新

我已经尝试将 JDBC 原子事务作为 java 中的代码。我强制第二个 sql 失败,但即使我指定 .setAutoCommit(false); dblink 影响了第一个查询的另一个数据库。我在没有 dblink 事务的情况下尝试了相同的代码,回滚效果很好。 dblink 是问题所在。

Java 更新

public static boolean ejecutarTransaccionDblink(String sql) {
boolean estado = false;
try {
Statement sentencia = conexion.createStatement();
conexion.setAutoCommit(false);
if (sql.length() != 0) {
if (sentencia.execute(sql)) {
conexion.commit();
estado = true;
}
}
} catch (SQLException ex) {
System.out.println(ex.toString());
try {
estado = false;
conexion.rollback();
} catch (SQLException ex1) {
}
} finally {
try {
conexion.setAutoCommit(true);
return estado;
} catch (SQLException ex) {
return estado;
}
}
}

感谢您的帮助。

最佳答案

为了在事务中运行查询,您只需将连接上的 auto-commit 特性设置为 false(记住在完成后将其设置回 true,尤其是如果连接是从连接池中检索的——因此被重用)。

代码比较简单:

ResultSet resultado = null;
String statement1 = "SELECT dblink_exec('hostaddr=xxx.xx.xxx.xxx port=5432 dbname=bdname user=myuser password=mypass connect_timeout=2','INSERT INTO table3(field4) VALUES (5)') AS result";
String statement2 = "SELECT dblink_exec('hostaddr=xxx.xx.xxx.xxx port=5432 dbname=bdname user=myuser password=mypass connect_timeout=2','UPDATE table1 SET field2 = field2 + 3.0 WHERE field1 = 16436') AS result";
try {
// set auto-commit to false, to indicate start of transaction
conexion.setAutoCommit(false);

// run whatever queries you want on the connection, in a transaction, e.g. :
Statement sentencia = conexion.createStatement();
resultado = sentencia.executeQuery(sql);

//manually commit the transaction when you're done
conexion.commit();

return resultado;
} catch (SQLException ex) {
System.out.println("Error Consulta:" + ex);

// ensure transaction is rolled-back in case of error. (note: you might want to add an NPE check here
con.rollback();
return null;
} finally {
// close any statements / preparedStatements, etc. Note you MUST do this in the finally block, to ensure your connection won't stay in transaction.
con.setAutoCommit(true);
}

希望对你有帮助

更新

正如@a_horse_with_no_name 所指出的,dblink_exec 连接到一个远程数据库,所以上面的内容并不完整,因为它只处理第一个数据库中的事务。

我认为答案应该在于使用 命名连接dblink_exec 过程涉及:

  • 使用 dblink_connect 打开新连接
  • 使用 dblink_exec 在新命名连接中启动事务
  • 在先前打开的连接中使用 dblink_exec 执行查询 1
  • 在先前打开的连接中使用 dblink_exec 执行查询 2
  • 在先前打开的连接中提交事务

因此,代码看起来像这样:

SELECT dblink_connect('myconn','hostaddr=xxx.xx.xxx.xxx port=5432 dbname=bdname user=myuser password=mypass connect_timeout=2');
SELECT dblink_exec('myconn','BEGIN');
SELECT dblink_exec('myconn', 'INSERT INTO table3(field4) VALUES (5)');
SELECT dblink_exec('myconn', 'UPDATE table1 SET field2 = field2 + 3.0 WHERE field1 = 16436');
SELECT dblink_exec('myconn','COMMIT');

问题是,这一切都未经测试,所以@KazMiller 你能试一试吗?

关于java - 将多个查询作为一个 dblink 事务执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36947037/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com