RabbitMQ и Hibernate: невозможно зафиксировать соединение JDBC

Я пытаюсь разработать небольшое приложение Springboot (используя JHipster), которое прослушивает очередь RabbitMQ, подтверждает сообщения, а затем выполняет некоторые операции в репозитории гибернации. На данный момент я могу потреблять сообщения без проблем. Но когда я пытаюсь использовать репозиторий гибернации при получении сообщения, кажется, что менеджеры транзакций путаются, и я получаю исключение:

Caused by: org.hibernate.TransactionException: Unable to commit against JDBC Connection
    at org.hibernate.resource.jdbc.internal.AbstractLogicalConnectionImplementor.commit(AbstractLogicalConnectionImplementor.java:92)
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:282)
 ...
Caused by: org.postgresql.util.PSQLException: Cannot commit when autoCommit is enabled.
    at org.postgresql.jdbc.PgConnection.commit(PgConnection.java:872)

Моя конфигурация Rabbit упрощена:

@Configuration
public class RabbitExchangeConfiguration {

    @Bean
    Queue queue() {
        return new Queue("myQueue", false);
    }
}

Затем есть мой TestService с RabbitListener (прослушивание) и метод, который использует мой диспетчер транзакций базы данных для доступа к репозиторию (тест)

@Service
public class TestService {

    public TestService(
        MyRepository myRepository
    ) {
        this.myRepository= myRepository;
    }

    // My Listener to receive the messages
    @RabbitListener(queues = "datafactory")
    public void listen(Message in) {
        String messageBody = new String(in.getBody());       
        test(messageBody);
    }

    // the method that should do stuff with the repository
    @Transactional(transactionManager = "myDatabaseTransactionManager")
    public void test(String content) {
        myRepository.findById(content).orElse(null);
        ..
    }
}

Сейчас меня не волнует, что содержит сообщение, и не важно, можно ли найти сущность.

Когда я закомментирую вызов test(content), сообщение будет получено (я вижу это в логах). Но когда я пытаюсь вызвать функцию, я получаю исключение.

Есть ли способ завершить транзакцию RabbitMQ перед входом в контекст транзакции гибернации? Почему слушатель пытается использовать транзакцию гибернации?

решено

Благодаря ответу p3consulting я обнаружил, что jpa.properties.hibernate.connection.provider_disables_autocommit=true установлено по умолчанию. JHipster автоматически настроил его для меня. Мне просто нужно было убедиться, что автокоммит отключен навсегда:

spring.datasource.hikari.auto-commit=false  // disables auto commit
spring.jpa.properties.hibernate.connection.provider_disables_autocommit=false   // makes sure it stays that way

Так что ничего общего с RabbitMQ...

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
0
60
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Сообщение ясно: вы оставили автофиксацию в TRUE, тогда вы не можете фиксировать явно, потому что это делается для вас после каждого оператора DML, вы можете отключить его с помощью hibernate.connection.autocommit=false в своих свойствах или вызовом connection.setAutoCommit(false);

Спасибо за ваш ответ. Я установил его на false (хотя соединение Hikari уже было установлено на autocommit: false. Это не решило проблему, просто сообщение об ошибке другое: JpaSystemException: Unable to commit against JDBC Connection; Похоже, что прослушиватель AMQP пытается использовать транзакцию JDBC. смысл для вас?

GameDroids 05.01.2023 20:57

Не из кода и трассировки стека, которые вы здесь показываете. Видите ли вы какой-либо метод, связанный с AMQP, в трассировке стека?

p3consulting 05.01.2023 21:05

Вы были правы, трассировка стека была связана с amqp только потому, что во время выполнения метода прослушивателя было выбрано исключение. Я протестировал настройку своей базы данных с другим подходом и увидел, что jpa.properties.hibernate.connection.provider_disables_autoco‌​mmit=true установлено по умолчанию. Простой provider_disables_autocommit=false решил мою проблему.

GameDroids 05.01.2023 21:42

Другие вопросы по теме