@Transactional в лямбда-выражениях - PullRequest
0 голосов
/ 12 марта 2020

Я использую @transactional для операций обновления БД в обычных функциях. Но в лямбда-выражении @transactional не допускается. Как справиться с этим? ниже мой код.

//normal function
  @Transactional
   void saveTransaction(String uniqueId) {
       Transaction transaction = new Transaction();
       transaction.setUniqueId(uniqueId);
       transactionRepository.save(transaction);
   }

   **@Transactional**  //Error Message - @Transactional not applicable to this field
   Consumer<String> saveTransaction = (uniqueId) ->
   {
       Transaction transaction = new Transaction();
       transaction.setUniqueId(uniqueId);
       transactionRepository.save(transaction);
   };

Ответы [ 3 ]

1 голос
/ 12 марта 2020

Вы можете использовать Programmati c управление транзакциями aproach.

Spring Framework предоставляет два способа программирования транзакций c:

  • Использование TransactionTemplate.
  • Использование непосредственной реализации PlatformTransactionManager.

Команда Spring обычно рекомендует TransactionTemplate для программного управления транзакциями c. Второй подход аналогичен использованию JTA UserTransaction API, хотя обработка исключений менее громоздка.

Сначала добавьте ссылку TransactionTemplate в ваш компонент.

  // single TransactionTemplate shared amongst all methods in this instance
  private final TransactionTemplate transactionTemplate;

Затем инициализируйте ваш атрибут Consumer<String> в методе инициализатора, помеченном @PostConstruct


        @PostConstruct
        public void init() {
            saveTransaction = (uniqueId) -> transactionTemplate.execute(new TransactionCallbackWithoutResult() {
                protected void doInTransactionWithoutResult(TransactionStatus status) {
                      Transaction transaction = new Transaction();
                      transaction.setUniqueId(uniqueId);
                      transactionRepository.save(transaction);
                }
            });
        }

Согласно Spring Docs:

Programmati c Управление транзакциями, как правило, хорошая идея только если у вас есть небольшое количество транзакционных операций. Например, если у вас есть веб-приложение, которое требует транзакции только для определенных операций обновления, вы можете не захотеть устанавливать транзакционные прокси с использованием Spring или любой другой технологии. В этом случае использование TransactionTemplate может быть хорошим подходом. Возможность задать имя транзакции в явном виде - это то, что может быть сделано только с помощью программного c подхода к управлению транзакциями.

Зачем использовать @PostConstruct?

0 голосов
/ 12 марта 2020

@Transactional применимо только к методам. Ваш saveTransaction является полем.

Для достижения желаемого поведения вам необходимо:

  • Объявить метод publi c и поместить в него свой код.
  • Инициализировать вас поле со ссылкой на этот метод. Имейте в виду, что по умолчанию пружина использует прокси для реализации @Transactional, поэтому this.myMethod не будет работать.
0 голосов
/ 12 марта 2020

@ Транзакционный может использоваться с функциями publi c только без переменных. Лямбда не является объявлением функции. Это как объявление переменной.

...