«1. Обзор

В этом руководстве мы обсудим различия между аннотациями org.springframework.transaction.annotation.Transactional и javax.transaction.Transactional.

Мы начнем с обзора их свойств конфигурации. Затем мы обсудим, к каким типам компонентов можно применить каждый из них и в каких обстоятельствах мы можем использовать тот или иной компонент.

2. Различия в конфигурации

Транзакционная аннотация Spring поставляется с дополнительной конфигурацией по сравнению с JTA-аналогом:

    Изоляция — Spring предлагает изоляцию на уровне транзакции через свойство изоляции; однако в JTA эта функция доступна только на уровне подключения. Распространение — доступно в обеих библиотеках через свойство распространения в Spring и свойство value в Java EE; Spring предлагает Nested в качестве дополнительного типа распространения Только для чтения — доступно только в Spring через свойство readOnly Timeout — доступно только в Spring через свойство timeout Rollback — обе аннотации предлагают управление откатом; JTA предоставляет свойства rollbackOn и dontRollbackOn, тогда как Spring имеет свойства rollbackFor и noRollbackFor, а также два дополнительных свойства: rollbackForClassName и noRollbackForClassName

2.1. Конфигурация аннотации Spring Transactional

В качестве примера давайте используем и настроим аннотацию Spring Transactional для простого автосервиса:

import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional(
  isolation = Isolation.READ_COMMITTED, 
  propagation = Propagation.SUPPORTS, 
  readOnly = false, 
  timeout = 30)
public class CarService {

    @Autowired
    private CarRepository carRepository;

    @Transactional(
      rollbackFor = IllegalArgumentException.class, 
      noRollbackFor = EntityExistsException.class,
      rollbackForClassName = "IllegalArgumentException", 
      noRollbackForClassName = "EntityExistsException")
    public Car save(Car car) {
        return carRepository.save(car);
    }
}

2.3. Конфигурация аннотаций JTA Transactional

Давайте сделаем то же самое для простой услуги аренды, используя аннотацию JTA Transactional:

import javax.transaction.Transactional;

@Service
@Transactional(Transactional.TxType.SUPPORTS)
public class RentalService {

    @Autowired
    private CarRepository carRepository;

    @Transactional(
      rollbackOn = IllegalArgumentException.class, 
      dontRollbackOn = EntityExistsException.class)
    public Car rent(Car car) {
        return carRepository.save(car);
    }
}

3. Применимость и взаимозаменяемость

Аннотация JTA Transactional применяется к компонентам, управляемым CDI, и к классам, определенным как управляемые. bean-компоненты по спецификации Java EE, тогда как аннотация Spring Transactional применяется только к bean-компонентам Spring.

Также стоит отметить, что поддержка JTA 1.2 появилась в Spring Framework 4.0. Таким образом, мы можем использовать аннотацию JTA Transactional в приложениях Spring. Однако обратное невозможно, поскольку мы не можем использовать аннотации Spring вне контекста Spring.

4. Заключение

В этом уроке мы обсудили различия между транзакционными аннотациями из Spring и JTA и когда мы можем использовать ту или иную.

Как всегда, код из этого руководства доступен на GitHub.