当前位置: 首页 > 知识库问答 >
问题:

混合JOOQ查询与JDBC事务

边国安
2023-03-14

我有一个用例,我想将jdbc事务与jooq上下文混合使用。

JDBC代码如下所示:

  public void inTransaction(InTransaction lambda) {
    DataSource ds = dataSource.get();
    try (Connection connection = ds.getConnection()) {
      try {
        logger.info("set autocommit to false");
        connection.setAutoCommit(false);
        try (Statement statement = connection.createStatement()) {
          lambda.execute(statement);
          logger.info("commiting transaction");
          connection.commit();
        }
      } catch (RuntimeException e) {
        logger.info("rolling back transaction");
        connection.rollback();
        throw e;
      } finally {
        logger.info("set autocommit to true");
        connection.setAutoCommit(true);
      }
    } catch (SQLException e) {
      throw new TilerException(e);
    }
  }

  @FunctionalInterface
  public interface InTransaction {
    void execute(Statement statement) throws SQLException;
  }

我希望lambda参数能够同时使用jdbc和jooq。

对于jdbc来说,使用语句非常简单。例如,像这样的图托拉尔:

 inTransaction(stmt -> {
   String SQL = "INSERT INTO Employees  " +
                "VALUES (106, 20, 'Rita', 'Tez')";
   stmt.executeUpdate(SQL);
   String SQL = "INSERTED IN Employees  " +
                "VALUES (107, 22, 'Sita', 'Singh')";
   stmt.executeUpdate(SQL);
 });

为了在同一事务上执行jooq查询,我必须获得一个上下文。我找到了一个api来从数据源/连接获取DSLContext
我不清楚的是,是否/如何从语句创建jooqDSLContext

共有2个答案

公羊涛
2023-03-14

如果要从jOOQ获取查询字符串,可以调用

String sqlString = query.getSQL()

然后在语句中使用此字符串:

stmt.executeUpdate(sqlString);
蓬弘
2023-03-14

您可以使用jOOQ的事务API完成所有这一切:

// Create this ad-hoc, or inject it, or whatever
DSLContext ctx = DSL.using(dataSource, dialect);

然后:

public void inJDBCTransaction(InJDBCTransaction lambda) {
    ctx.transaction(config -> {
        config.dsl().connection(connection -> {
            try (Statement statement = connection.createStatement()) {
                lambda.execute(statement);
            }
        });
    });
}

public void inJOOQTransaction(InJOOQTransaction lambda) {
    ctx.transaction(config -> lambda.execute(config.dsl()));
}

@FunctionalInterface
public interface InJDBCTransaction {
    void execute(Statement statement) throws SQLException;
}

@FunctionalInterface
public interface InJOOQTransaction {
    void execute(DSLContext ctx);
}

您的最终代码:

inJDBCTransaction(stmt -> {
    String SQL = "INSERT INTO Employees  " +
                 "VALUES (106, 20, 'Rita', 'Tez')";
    stmt.executeUpdate(SQL);
    String SQL = "INSERTED IN Employees  " +
                 "VALUES (107, 22, 'Sita', 'Singh')";
    stmt.executeUpdate(SQL);
});

inJOOQTransaction(ctx -> {
    ctx.insertInto(EMPLOYEES).values(106, 20, "Rita", "Tez").execute();
    ctx.insertInto(EMPLOYEES).values(107, 22, "Sita", "Singh").execute();
});

我不太相信jOOQ和JDBC需要这种抽象。jOOQ从不向您隐藏JDBC。当使用DSLContext.connection()方法时,您总是可以访问JDBC API,如上所示。所以,如上所示:

  • jOOQ事务API做的正是您计划做的事情。在事务性上下文中包装lambda,成功时提交,失败时回滚(版本的回滚不起作用,因为它捕获了错误的异常)。
  • 如果需要JDBC逃生舱口,jOOQ可以提供

在许多RDBMS中,您不希望在静态JDBC语句上运行查询。您将希望使用准备语句来代替,因为:

  • 您将受益于执行计划缓存(并减少缓存上的争用)
 类似资料:
  • 我如何写问题。*在jooq中而不是指定所有实体vaiables

  • 我正试图用jooq编写这个查询 我尝试了几件事,但没有成功。到目前为止,我只得到 如何将num列添加到结果中?感谢您的帮助。

  • 基本上,我有一组顶点ID,我想遍历并从某些外边找到一组顶点。我想把外边后面的顶点与它来自的准确性联系起来。例如:,所以v1有2个输出边(e1和e2)到v2和v4,而v3有2个输出边(e3和e4)到v5和v6。我想要的是得到如下所示的遍历结果 有人能帮我使用Gremlin遍历吗?最接近的例子是

  • 我正在使用合流kafka connect jdbc源将mysql表中的记录推送到我的kafka主题,但似乎日期列被转换为纪元时间。 这是我的配置: kafka主题中的输出: 我也在类似于“select from_unixtime(updated _ on)from temp”的查询中尝试了from _ unixtime(),但是那不行。 有没有办法推到YYYY-MM-DD HH:MM:SS格式的K

  • 当以下转换在将RDD写入文件之前执行时,它们之间有什么区别? 聚结(1,洗牌=true) 合并(1,洗牌=假) 代码示例: 它与collect()相比如何?我完全知道Spark save方法将以HDFS风格的结构存储它,但我更感兴趣的是collect()和shuffled/non shuffled coalesce()的数据分区方面。

  • 问题内容: 我正在尝试以下MySQL查询来获取一些数据: 但是我总是得到以下错误: 该列确实存在,并且查询仅适用于一个表(例如,当我卸下电话时) 有人知道我做错了吗? 问题答案: 似乎您的要求是联接表,但您正在联接表。只是改变他们的顺序。 希望这对您有所帮助。谢谢!!