问题描述
我一直在阅读但我很难看到如何在实践中实现它。
I've been reading about transactions & jooq but I struggle to see how to implement it in practice.
假设我提供了一个自定义 ConnectionProvider $的JOOQ c $ c>恰好使用自动提交设置为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交易API
使用jOOQ 3.4,以通过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();
});
或者使用pre-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:
- 正常完成后提交
- 在异常时回滚
可用于覆盖默认行为,该行为通过JDBC使用。
The org.jooq.TransactionProvider
SPI can be used to override the default behaviour, which implements nestable transactions via JDBC using Savepoints
.
当前文档显示了使用Spring进行事务处理时的示例:
The current documentation shows an example when using Spring for transaction handling:
- http://www.jooq.org/doc/latest/manual/getting-started/tutorials/jooq-with-spring/
这个例子基本归结为使用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:
- https://github.com/jOOQ/jOOQ/tree/master/jOOQ-examples/jOOQ-spring-example
虽然我个人不推荐它,但有些用户已经成功用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:
- https://github.com/jOOQ/jOOQ/tree/master/jOOQ-examples/jOOQ-spring-guice-example
这篇关于JOOQ&交易的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!