Различия между Grails @Transactional и аннотациями Spring @Transactional

Ну, был момент в декларативных сделках Grails. Он сказал:

Grails.transaction.Transactional аннотация была впервые введена в Grails 2.3. До 2.3 использовалась аннотация Spring @Transactional.

Но я не могу понять, в чем главное различие между этими двумя аннотациями. Почему аннотация Spring не использовалась в будущих выпусках?

Ответы

Ответ 1

Я хотел бы затронуть этот комментарий: "Однако в 2.3 команда почувствовала, что это хорошая идея (я не согласен лично) представить новую аннотацию, которая может применяться не только к Услугам, но и к Контроллерам".

Никогда не было основной целью команды Grails ввести аннотацию, которая могла бы использоваться как для контроллеров, так и для служб. Наше основное намерение состояло в том, чтобы ввести AST-преобразование, которое устраняло необходимость в прокси-сервере и выполнялось лучше, чем Spring s @Transactional. Grails @Transactional прокладывает необходимую логику для обработки транзакций непосредственно в байтовый код и не нуждается в прокси-сервере, поэтому мы считаем, что это лучше, чем версия Spring.

Тот факт, что он также работает на контроллерах, является лишь побочным эффектом вышеизложенного, который мы обнаружили. Сказав, что в нашем опыте слишком много пользователей Grails неправильно демаркируют свои транзакционные границы при использовании контроллеров. Если вы отмечаете действие контроллера как доступное только для чтения, то Hibernate не должен выполнять грязную проверку любых запросов, которые вы выполняете в рамках действия. Это значительно улучшает производительность приложений Grails и может быть очень хорошим.

Мы абсолютно поощряем разделение логики на сервисы, но если вы рассмотрите следующий тривиальный пример:

  @Transactional(readOnly=true)
  def show(Long id) {
       respond Foo.get(id)
  }

Это слишком сложно представить сервис для такого тривиального действия, но если вы не демаркируете запрос с транзакцией только для чтения, то Hibernate выполняет грязную проверку экземпляра, который наносит ущерб производительности.

Обновление 22/02/16: Начиная с версии Grails 3.1 версия Spring считается устаревшей и по умолчанию отключена (при необходимости вы можете снова включить ее)

Ответ 2

Еще одно отличие от версии аннотации Grails 2.3 заключается в том, что если вы вызываете метод B из метода A в той же службе, будет выполняться атрибут транзакции по методу B. С аннотацией Spring это не будет выполнено, потому что вы обходите динамический прокси-сервер, где применяются транзакции.

def methodA() {
    methodB()
}

@Transactional
def methodB() {
    ...
}

Ответ 3

До 2.3 аннотация Spring была использована, поскольку она была применена к Services. Это просто Spring beans. Однако в 2.3 команда почувствовала, что это хорошая идея (я не согласен лично) представить новую аннотацию, которая может применяться не только к Услугам, но и к Контролерам. Разница в том, что версия аннотации Grails 2.3 делает много магии преобразования АСТ для работы в концепции контроллера Grails.

Надеюсь, что это поможет.

Обновление

Функционально говоря, при применении к сервисам Grails verson аннотации идентична версии Spring. Хотя он несколько более эффективен, так как при преобразовании АСТ применяется к вашему коду во время компиляции, а не к прокси, применяемому во время выполнения.

Ответ 4

Почему аннотация spring не использовалась в будущих выпусках?

Вы можете использовать аннотацию spring. Версия Grails более гибкая и более эффективная, потому что мы можем собрать много логики во время компиляции, но версия spring все еще существует и по-прежнему ведет себя так же, как и она.

Ответ 5

@PrakashJoshi сказал:

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

Это зависит от того, к чему у вас настроено поведение транзакционного распространения (устанавливается в аннотации). PROPAGATION_REQUIRED (по умолчанию) будет продолжать существовать, но PROPAGATION_NEW запустит новый, приостановив текущий.

Ответ 6

Вы все еще можете использовать аннотацию spring, но версия grails быстрее и лучше знает фреймворк.

Я настоятельно рекомендую вам использовать версию Grails.