Публикация транзакционных событий Spring Modulith останавливает соединения JDBCJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Публикация транзакционных событий Spring Modulith останавливает соединения JDBC

Сообщение Anonymous »

Введение
Недавно я представил Spring Modulith в одном из наших приложений и использовал @ApplicationModuleListener для прослушивания событий, опубликованных из метода. внутри приложения, помеченный Spring @Transactional. Вся установка работает так, как ожидалось. События публикуются, а записи о них записываются в таблицу (

Код: Выделить всё

event_publication
) в нашей базе данных.

Проблема заключается в том, что приложение зависает после нескольких запусков, поскольку в нашей базе данных больше нет доступных соединений JDBC. пул соединений для обработки дальнейших запросов от операций/потоков, которым это необходимо.

Пояснение ниже
В настоящее время приложение структурировано следующим образом:

Код: Выделить всё

class AppScheduler {
final ApplicationEventPublisher eventPublisher;

@Transactional
@Scheduled(initialDelay = 120_000, fixedDelay = 120_000)
public void execute() {

final String operationID = UUID.randomUUID().toString();
eventPublisher.publishEvent(ApplicationCustomEvents.AEvent(operationID));
eventPublisher.publishEvent(ApplicationCustomEvents.BEvent(operationID));
}
}

Код: Выделить всё

class AEventListener {

final ALogicsAggregator aLogicsAggregator;

@ApplicationModuleListener
void on(ApplicationCustomEvents.AEvent evt) {
aLogicsAggregator.execute(evt);
}
}

Код: Выделить всё

class BEventListener {

final BLogicsAggregator bLogicsAggregator;

@ApplicationModuleListener
void on(ApplicationCustomEvents.BEvent evt) {
bLogicsAggregator.execute(evt);
}
}

Код: Выделить всё

//Similar design BLogicsAggregator as well
class ALogicsAggregator {
final ALogic1 aLogic1;
final ALogic2 aLogic2;
final ALogicN aLogicN;

void execute(AEvent evt) {
//Distribute operations to ALogic1... ALogicN, depending on some known conditions
//Each of the logic 1...N, are executed one after the other.
//The operation within each logic is held as a SET and are run in parallel
//At some point in ALogic's execution Network calls are made to external systems
//At some point in ALogic's execution READS and WRITES are done to the DB
//Separate Transactions are opened for the WRITE action to the DB
//Within the logic, parallel executions are initiated where necessary
aLogic1.excute(Set);
aLogic2.excute(Set);
aLogicN.excute(Set);
}
}
Поскольку я использую Spring-data-jpa, у меня автоматически настроены параметры пула соединений Hikari, когда я впервые столкнулся с ошибкой, я подумал, что настроенных значений по умолчанию недостаточно. , я попробовал настроить размер пула (увеличив его выше 10 и уменьшив ниже десяти). После нескольких запусков приложение начинает выдавать ошибки - о том, что оно не может получить соединение JDBC.

Код: Выделить всё

org.springframework.dao.DataAccessResourceFailureException: Unable to acquire JDBC Connection [AppDBConnPool - Connection is not available, request timed out after 30005ms (total=5, active=5, idle=0, waiting=2)] [n/a]
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:274) ~[spring-orm-6.2.0.jar:6.2.0]
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:241) ~[spring-orm-6.2.0.jar:6.2.0]
Когда я смотрю на компонент Hikari JMX Bean в JConsole, я вижу, что соединения в пуле подключений к базе данных активно используются, но никогда не освобождаются, и есть по крайней мере один ожидающий поток/операция. получить соединение с БД (если оно когда-либо станет доступным).
Моя попытка исправить
Я не уверен откуда конкретно возникла проблема, но когда я удаляю @Transactional из класса публикации событий и замените @ApplicationModuleListerner Spring Modulith в классах прослушивателя на @Async + @EventLister (из Spring), даже при подключении к базе данных размер пула равен 5, приложение никогда не останавливается. Есть некоторые моменты, когда большинство/все доступные соединения с БД в пуле используются, но в конечном итоге они освобождаются, а другие операции/потоки выбирают и используют их снова. Я не сталкивался с ситуацией, когда соединения удерживались дольше, чем обычно.
Моя гипотеза
У меня есть предположение, что между транзакцией, созданной/открытой в момент, когда событие было опубликовано, и те, которые открывались, когда я пишу в БД, все портят, я не могу сказать, как и почему, а без аннотации @Transactional в методе публикации событий прослушиватели событий, отмеченные @ApplicationModuleListener, не могут получать опубликованные события.
Пожалуйста, помогите/посоветуйте, что я делаю неправильно и как мне решить эту проблему.
Спасибо

Подробнее здесь: https://stackoverflow.com/questions/792 ... onnections
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»