Hibernate и JOOQ делятся транзакциями - PullRequest
1 голос
/ 17 октября 2019

Я пытаюсь поместить jOOQ в спящий режим в существующий большой сервис. Код работает как обслуживаемый, за исключением одной проблемы: кажется, что запросы jOOQ не обращают внимания на транзакции Spring (подход, основанный на аннотациях).

Проблема состоит в том, что в одном и том же стеке вызовов есть некоторые операции гибернации (репозитории),и jOOQ не видит эти объекты, а hibernate - видит. Я подозреваю, что проблема в определении бина, в отдельных менеджерах транзакций, или нет. Обратите внимание, что я не использую приложение бота 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 Ответ

0 голосов
/ 18 октября 2019

Если вы разрешите Spring Boot настроить jOOQ DSLContext, а за кулисами Configuration и ConnectionProvider, у вас не должно возникнуть транзакционных проблем. Однако обратите внимание, что Hibernate, возможно, не сбросил изменения, примененные к его кэшам, в базу данных, и jOOQ запрашивает только базу данных напрямую, а не кэш Hibernate.

Следовательно, вы должны всегда сбрасывать сеанс Hibernate. до запуска любого jOOQ (или JDBC, или других собственных запросов SQL).

...