Transactional Annotations: Spring vs. JTA – 事务性注解 Spring vs. JTA

最后修改: 2020年 5月 12日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this tutorial, we’ll discuss the differences between org.springframework.transaction.annotation.Transactional and javax.transaction.Transactional annotations.

在本教程中,我们将讨论org.springframework.transaction.annotation.Transactionaljavax.transaction.Transactional注解的区别

We’ll start with an overview of their configuration properties. Then, we’ll discuss what types of components each can be applied to, and in which circumstances we can use one or the other.

我们将从概述它们的配置属性开始。然后,我们将讨论它们各自可以应用于哪些类型的组件,以及在哪些情况下我们可以使用其中之一。

2. Configuration Differences

2.配置差异

Spring’s Transactional annotation comes with additional configuration compared to its JTA counterpart:

与JTA相比,Spring的Transactional注解有额外的配置。

  • Isolation – Spring offers transaction-scoped isolation through the isolation property; however, in JTA, this feature is available only at a connection level
  • Propagation – available in both libraries, through the propagation property in Spring, and the value property in Java EE; Spring offers Nested as an additional propagation type
  • Read-Only – available only in Spring through the readOnly property
  • Timeout – available only in Spring through the timeout property
  • Rollback – both annotations offer rollback management; JTA provides the rollbackOn and dontRollbackOn properties, while Spring has rollbackFor and noRollbackFor, plus two additional properties: rollbackForClassName and noRollbackForClassName

2.1. Spring Transactional Annotation Configuration

2.1.Spring Transactional 注释配置

As an example, let’s use and configure the Spring Transactional annotation on a simple car service:

作为一个例子,让我们在一个简单的汽车服务上使用和配置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 Annotation Configuration

2.3.JTA 事务型 注释配置

Let’s do the same for a simple rental service using the JTA Transactional annotation:

让我们对一个使用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. Applicability and Interchangeability

3.适用性和互换性

JTA Transactional annotation applies to CDI-managed beans and classes defined as managed beans by the Java EE specification, whereas Spring’s Transactional annotation applies only to Spring beans.

JTA的Transactional注解适用于CDI管理的Bean和被Java EE规范定义为管理Bean的类,而Spring的Transactional注解仅适用于Spring Bean。

It’s also worth noting that support for JTA 1.2 was introduced in Spring Framework 4.0. Thus, we can use the JTA Transactional annotation in Spring applications. However, the other way around is not possible since we can’t use Spring annotations outside the Spring context.

还值得注意的是,Spring Framework 4.0中引入了对JTA 1.2的支持。因此,我们可以在Spring应用程序中使用JTA的Transactional注解。然而,反过来就不可能了,因为我们不能在Spring上下文之外使用Spring注解。

4. Conclusion

4.总结

In this tutorial, we discussed the differences between Transactional annotations from Spring and JTA, and when we can use one or another.

在本教程中,我们讨论了来自Spring和JTA的Transactional annotations之间的区别,以及我们何时可以使用其中之一。

As always, the code from this tutorial is available over on GitHub.

一如既往,本教程的代码可在GitHub上获得over。