Я пытаюсь разработать небольшое приложение 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...
Сообщение ясно: вы оставили автофиксацию в TRUE, тогда вы не можете фиксировать явно, потому что это делается для вас после каждого оператора DML, вы можете отключить его с помощью hibernate.connection.autocommit=false
в своих свойствах или вызовом connection.setAutoCommit(false);
Не из кода и трассировки стека, которые вы здесь показываете. Видите ли вы какой-либо метод, связанный с AMQP, в трассировке стека?
Вы были правы, трассировка стека была связана с amqp только потому, что во время выполнения метода прослушивателя было выбрано исключение. Я протестировал настройку своей базы данных с другим подходом и увидел, что jpa.properties.hibernate.connection.provider_disables_autocommit=true
установлено по умолчанию. Простой provider_disables_autocommit=false
решил мою проблему.
Спасибо за ваш ответ. Я установил его на
false
(хотя соединение Hikari уже было установлено наautocommit: false
. Это не решило проблему, просто сообщение об ошибке другое:JpaSystemException: Unable to commit against JDBC Connection;
Похоже, что прослушиватель AMQP пытается использовать транзакцию JDBC. смысл для вас?