当前位置: 首页 > 面试题库 >

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

司马弘益
2023-03-14
问题内容

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

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您可以尝试一下吗?



 类似资料:
  • 最近,我们正在为我们的应用程序解决一个性能问题,该代码最初是基于Corda教程代码的M13版本构建的,我们遵循了Corda的版本,现在更新为V2.0。业务很简单,甲方以表单的形式上传一份包含一些元数据的合同文档,然后将此事务发送给乙方,我们在验证功能中定义了一些简单的条件,因此,通常事务将在没有任何手动操作的情况下完成。但如果我们在本地环境中这样做,这个过程大约需要3秒钟(一个2.9M附件),但当

  • 在Liquibase论坛的一次讨论中,开发人员Nathan Voxland说Liquibase应该在每个变更集之后提交。我知道这是一个七年前的线程,所以从那以后可能发生了很多变化,但也许没有? 它应该在变更集之后提交。在大多数数据库上,addColumn也会自动提交。 changeSet标记的文档可以解释为“在changelog中的所有前提条件成功之后提交”,这与7年前的帖子相矛盾。 我有一个ma

  • 我需要创建一个具有架构列表的@Scheduled方法,对于每个架构,从2个表中删除行。 我将deleteFromCustomerTables定义为@Transactional(propagation=propagation.REQUIRES_NEW),并在其中使用EntityManager从2个表中删除行。 为了使其工作,我需要将@Transactional添加到计划FixedDelayTask,

  • 问题内容: 我是JDBC的新手,我正在尝试更新数据库中的2个表,因此我想在1个事务中进行操作,因此,如果一个查询失败,另一个查询也会失败。我想提供这样的行为,或者如果其中一个失败,则有机会进行回滚。 这是我的两个查询: 问题答案: 如果要自动执行多个语句,则需要使用一个事务。JDBC连接默认为“自动提交”模式,这意味着每个语句都在其自己的事务中执行。因此,您首先需要使用禁用自动提交模式。 在禁用自

  • 问题内容: 我有两个查询,如下所示: 我想一次执行两个查询。 但是,然后告诉我如何处理每个单独设置的表。实际上,在ASP.NET中,我们使用数据集来处理两个查询, 如何使用PHP / MYSQL做同样的事情? 问题答案: 更新: 显然可以通过将标志传递给。请参阅使用PHP在一条语句中执行多个SQL查询。尽管如此,任何当前的读者都应避免使用-class函数,而更喜欢PDO。 您无法使用PHP中的常规

  • 到目前为止,我们主要通过.await来使用 Futures,它将阻塞当前任务,直到特定的Future完成。但是,真正的异步应用程序,通常需要同时执行几个不同的操作。 Executing Multiple Futures at a Time 在本章中,我们将介绍几种,同时执行多个异步操作的方法: join!:等待全部 Futures 完成 select!:等待几种 Futures 之一,完成 Spa