【问题标题】:Hibernate and jOOQ sharing a transactionHibernate 和 jOOQ 共享事务
【发布时间】: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;
        }

    }
}

【问题讨论】:

    标签: java spring hibernate jooq


    【解决方案1】:

    如果您让 Spring Boot 配置 jOOQ 的 DSLContext,以及在幕后配置 ConfigurationConnectionProvider,那么您应该不会遇到事务问题。但是请注意,Hibernate 可能没有将应用于其缓存的更改刷新到数据库,并且 jOOQ 仅直接查询数据库,而不是任何 Hibernate 缓存。

    因此,您必须确保在运行任何 jOOQ(或 JDBC,或其他本机 SQL 查询)之前始终刷新 Hibernate 的会话。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-20
      • 2018-09-15
      • 2010-12-09
      • 1970-01-01
      • 2017-02-20
      • 1970-01-01
      • 2014-01-05
      • 1970-01-01
      相关资源
      最近更新 更多