Создание новой сущности в новой транзакции в том же потоке

Добрый день!

Есть задачка: создать новую сущность в отдельной транзакции в том же потоке, в котором выполняется основная транзакция. Пробовал разные варианты реализации, но безуспешно. Пробовал автоматическое создание транзакции с помощью аннотации @Transactional(propagation = Propagation.REQUIRES_NEW) на методе.
Пробовал создавать транзакцию вручную таким образом:

@Autowired
private UnconstrainedDataManager systemDataManager;

@Autowired
PlatformTransactionManager transactionManager;

private final TransactionTemplate transactionTemplate;

this.transactionTemplate = new TransactionTemplate(transactionManager);
this.transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);

res = this.transactionTemplate.execute(status -> {
    ExtEntity e = systemDataManager.create(ExtEntity.class);
    e.setName(key);
    systemDataManager.save(e); 
});

И вызываю этот код из другого метода, который выполняется в своей транзакции. В результате приложение зависает на комите внутренней транзакции. Видимо он ждёт комита внешней транзакции.

Может кто-то делал что-то подобное? Буду благодарен за совет

Ваш код и вообще кейс вполне валидный.
Скорее всего во внутренней транзакции вы пытаетесь использовать какие-то данные, которые еще не закоммичены внешней транзакцией, поэтому БД зависает в ожидании. Если данные транзакций независимы, никаких зависаний быть не должно.

С уважением,
Константин

Константин, спасибо!
Разобрался. Как всегда проблем было сразу несколько. Во-первых в моих тестах заканчивались сессии в Hikari ConnectionPool и приложение зависало на ожидании получения сессии из пула. По умолчанию в Hikari всего 10 сессий в пуле. Для меня это оказалось маловато. Пришлось увеличивать:

main.datasource.hikari.maximumPoolSize=32

Во-вторых, тесты я пускаю на базе HSQLDB. У неё есть три режима управления транзакциями: LOCKS, MVLOCKS, MVCC. Режим по умолчанию - это LOCKS. Он блокирует целиком таблицы shared lock-ом при чтении и exclusive lock-ом при записи. Я поменял режим на MVCC:

main.datasource.url = jdbc:hsqldb:mem:mydb;hsqldb.tx=MVCC

В этом режиме блокируются отдельные строки, а не целиком таблицы. Сразу приложение задышало. Осталось непонятным, почему не срабатывало автоопределение deadlock-а при зависании, но это уже другой вопрос.
Всем спасибо!

Немного некорректно в предыдущем сообщении написал. Хочу поправить. В ходе исследований я сделал вывод, HSQLDB не умеет блокировать отдельные строки в таблице, т.е. SELECT ... FOR UPDATE блокирует целиком таблицу в режимах управления транзакциями LOCKS, MVLOCKS. Режим MVCC отключает эту блокировку и в нём выражение SELECT ... FOR UPDATE вообще не имеет никакого смысла.

1 симпатия