JOOQ &交易 [英] JOOQ & transactions

查看:20
本文介绍了JOOQ &交易的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在阅读有关交易和jooq 但我很难看到如何在实践中实现它.

I've been reading about transactions & jooq but I struggle to see how to implement it in practice.

假设我为 JOOQ 提供了一个自定义的 ConnectionProvider,它恰好使用了一个自动提交设置为 false 的连接池.

Let's say I provide JOOQ with a custom ConnectionProvider which happens to use a connection pool with autocommit set to false.

实现大致如下:

@Override public Connection acquire() throws DataAccessException {
    return pool.getConnection();
}

@Override public void release(Connection connection) throws DataAccessException {
    connection.commit();
    connection.close();
}

我将如何将两个 jooq 查询包装到一个事务中?

How would I go about wrapping two jooq queries into a single transaction?

使用 DefaultConnectionProvider 很容易,因为只有一个连接 - 但是使用池我不知道如何去做.

It is easy with the DefaultConnectionProvider because there's only one connection - but with a pool I'm not sure how to go about it.

推荐答案

jOOQ 3.4 Transaction API

使用 jOOQ 3.4,事务 API已添加到 JDBC、Spring 或 JTA 事务管理器上的抽象.此 API 可用于 Java 8,例如:

jOOQ 3.4 Transaction API

With jOOQ 3.4, a transaction API has been added to abstract over JDBC, Spring, or JTA transaction managers. This API can be used with Java 8 as such:

DSL.using(configuration)
   .transaction(ctx -> {
       DSL.using(ctx)
          .update(TABLE)
          .set(TABLE.COL, newValue)
          .where(...)
          .execute();
   });

或者使用 Java 8 之前的语法

Or with pre-Java 8 syntax

DSL.using(configuration)
   .transaction(new TransactionRunnable() {
       @Override
       public void run(Configuration ctx) {
           DSL.using(ctx)
              .update(TABLE)
              .set(TABLE.COL, newValue)
              .where(...)
              .execute();
       }
   });

这个想法是 lambda 表达式(或匿名类)形成事务代码,其中:

The idea is that the lambda expression (or anonymous class) form the transactional code, which:

  • 在正常完成时提交
  • 出现异常时回滚

org.jooq.TransactionProvider SPI 可用于覆盖默认行为,该行为使用 保存点.

当前文档显示了使用 Spring 进行事务处理的示例:

The current documentation shows an example when using Spring for transaction handling:

这个例子本质上归结为使用 Spring TransactionAwareDataSourceProxy

This example essentially boils down to using a Spring TransactionAwareDataSourceProxy

<!-- Using Apache DBCP as a connection pooling library.
     Replace this with your preferred DataSource implementation -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
    init-method="createDataSource" destroy-method="close">
    <property name="driverClassName" value="org.h2.Driver" />
    <property name="url" value="jdbc:h2:~/maven-test" />
    <property name="username" value="sa" />
    <property name="password" value="" />
</bean>

<!-- Using Spring JDBC for transaction management -->
<bean id="transactionManager"
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
</bean>

<bean id="transactionAwareDataSource"
    class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy">
    <constructor-arg ref="dataSource" />
</bean>

<!-- Bridging Spring JDBC data sources to jOOQ's ConnectionProvider -->
<bean class="org.jooq.impl.DataSourceConnectionProvider" 
      name="connectionProvider">
    <constructor-arg ref="transactionAwareDataSource" />
</bean>

可从 GitHub 获取运行示例:

A running example is available from GitHub here:

虽然我个人不推荐它,但一些用户已经成功地用 Guice 替换了 Spring 的部分 DI 并使用 Guice 处理事务.GitHub 上还有一个针对此用例的集成测试运行示例:

Although I personally wouldn't recommend it, some users have had success replacing a part of Spring's DI by Guice and handle transactions with Guice. There is also an integration-tested running example on GitHub for this use-case:

这篇关于JOOQ &amp;交易的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆