Hibernate 和 jOOQ 共享事务
Posted
技术标签:
【中文标题】Hibernate 和 jOOQ 共享事务【英文标题】:Hibernate and jOOQ sharing a transaction 【发布时间】:2020-02-14 18:15:09 【问题描述】:我正在尝试将 jOOQ 与 hibernate 一起放在现有的大型服务中。代码按照有人参与的方式工作,保存一个问题:jOOQ 查询似乎忽略了 Spring 事务(基于注释的方法)。
问题在于,在同一个调用堆栈中有一些休眠操作(存储库),jOOQ 看不到这些实体,而休眠可以。 我怀疑问题出在 bean 定义、单独的事务管理器或其他问题上。 请注意,我使用的不是 Spring 机器人应用程序,而是“普通”Spring(版本 5.0.8-RELEASE)。
配置是从 Spring autoconfig 复制而来的:
@Configuration
public class JooqAutoConfiguration
@Bean
public DataSourceConnectionProvider dataSourceConnectionProvider(DataSource dataSource)
return new DataSourceConnectionProvider(new TransactionAwareDataSourceProxy(dataSource));
@Bean
public SpringTransactionProvider transactionProvider(PlatformTransactionManager txManager)
return new SpringTransactionProvider(txManager);
@Bean
@Order(0)
public DefaultExecuteListenerProvider jooqExceptionTranslatorExecuteListenerProvider()
return new DefaultExecuteListenerProvider(new JooqExceptionTranslator());
@Configuration
public static class DslContextConfiguration
private final ConnectionProvider connection;
private final DataSource dataSource;
private final TransactionProvider transactionProvider;
private final RecordMapperProvider recordMapperProvider;
private final RecordUnmapperProvider recordUnmapperProvider;
private final Settings settings;
private final RecordListenerProvider[] recordListenerProviders;
private final ExecuteListenerProvider[] executeListenerProviders;
private final VisitListenerProvider[] visitListenerProviders;
private final TransactionListenerProvider[] transactionListenerProviders;
private final ExecutorProvider executorProvider;
public DslContextConfiguration(ConnectionProvider connectionProvider,
DataSource dataSource, ObjectProvider<TransactionProvider> transactionProvider,
ObjectProvider<RecordMapperProvider> recordMapperProvider,
ObjectProvider<RecordUnmapperProvider> recordUnmapperProvider, ObjectProvider<Settings> settings,
ObjectProvider<RecordListenerProvider[]> recordListenerProviders,
ExecuteListenerProvider[] executeListenerProviders,
ObjectProvider<VisitListenerProvider[]> visitListenerProviders,
ObjectProvider<TransactionListenerProvider[]> transactionListenerProviders,
ObjectProvider<ExecutorProvider> executorProvider)
this.connection = connectionProvider;
this.dataSource = dataSource;
this.transactionProvider = transactionProvider.getIfAvailable();
this.recordMapperProvider = recordMapperProvider.getIfAvailable();
this.recordUnmapperProvider = recordUnmapperProvider.getIfAvailable();
this.settings = settings.getIfAvailable();
this.recordListenerProviders = recordListenerProviders.getIfAvailable();
this.executeListenerProviders = executeListenerProviders;
this.visitListenerProviders = visitListenerProviders.getIfAvailable();
this.transactionListenerProviders = transactionListenerProviders.getIfAvailable();
this.executorProvider = executorProvider.getIfAvailable();
@Bean
public DefaultDSLContext dslContext(org.jooq.Configuration configuration)
return new DefaultDSLContext(configuration);
@Bean
public DefaultConfiguration jooqConfiguration()
DefaultConfiguration configuration = new DefaultConfiguration();
configuration.set(SQLDialect.mysql);
configuration.set(this.connection);
if (this.transactionProvider != null)
configuration.set(this.transactionProvider);
if (this.recordMapperProvider != null)
configuration.set(this.recordMapperProvider);
if (this.recordUnmapperProvider != null)
configuration.set(this.recordUnmapperProvider);
if (this.settings != null)
configuration.set(this.settings);
if (this.executorProvider != null)
configuration.set(this.executorProvider);
configuration.set(this.recordListenerProviders);
configuration.set(this.executeListenerProviders);
configuration.set(this.visitListenerProviders);
configuration.setTransactionListenerProvider(this.transactionListenerProviders);
return configuration;
【问题讨论】:
【参考方案1】:如果您让 Spring Boot 配置 jOOQ 的 DSLContext
,以及在幕后配置 Configuration
和 ConnectionProvider
,那么您应该不会遇到事务问题。但是请注意,Hibernate 可能没有将应用于其缓存的更改刷新到数据库,并且 jOOQ 仅直接查询数据库,而不是任何 Hibernate 缓存。
因此,您必须确保在运行任何 jOOQ(或 JDBC,或其他本机 SQL 查询)之前始终刷新 Hibernate 的会话。
【讨论】:
以上是关于Hibernate 和 jOOQ 共享事务的主要内容,如果未能解决你的问题,请参考以下文章
如何配置 Spring 使 JPA(Hibernate)和 JDBC(JdbcTemplate 或 MyBatis)共享同一个事务