Я попросил уточнить, как вы вызываете метод, потому что одной простой ошибкой в настройке на основе Spring (Boot) является недопонимание того, как работает @Transactional.
В частности, учитывая настройки по умолчанию, аннотация @Transactional работает только тогда, когда экземпляр класса с вызываемым аннотированным методом был создан через Spring и вызван через Spring, а не напрямую из другого метода в том же классе.
Обычно это означает, что у вас есть экземпляр
@Autowired
CoolClass classInstance;
, а затем вы go с
classInstance.transactionalMethod
, где этот метод представляет собой аннотацию с @ Transactional
@Transactional
public void transactionalMethod(...){
Если вместо этого вы позвоните
classInstance.someOtherMethod()
, где
public void someOtherMethod(){
this.transactionalMethod(...);
}
, это не сработает.
Аналогично, если вы создадите свой класс вручную, например, так:
CoolClass classInstance=new CoolClass(..);
if также не будет работать.
Это из-за того, что Spring в настройках по умолчанию поддерживает @Transactional. Это поведение можно изменить, переключив диспетчер транзакций в режим ткачества AspectJ (см. Здесь https://docs.spring.io/spring/docs/4.2.x/spring-framework-reference/html/transaction.html).
В итоге, чтобы аннотация @Transactional работала правильно с режимом прокси по умолчанию :
- метод должен быть опубликован c
- вызов должен поступать извне (управляемого пружиной) компонента
(И это мои дорогие друзья, почему аннотация SpringTransactional - милая маленькая ловушка-ловушка - выглядит красиво, невинно и круто, но может серьезно сжечь вас, молча подведя вас.)