我们是否需要在 Spring 中同时使用 @Transactional 和 @Modifying 注解?

Lif*_*rld 11 java spring transactions spring-transactions

我仍然试图围绕@Transactional 的工作原理进行思考。

@Transactional对 Service 类的方法进行了@Modifying注释,对 Repository 类中的方法进行了注释。带@Transactional注释的方法是否适用于带注释的 Repository 中的方法@Modifying

我的理解:

@Transactional@Transactional( readOnly = true )没有数据的类的方法上写入数据库,而在使用 时@Transactional,数据写入数据库。

修改查询

  1. 修改方法签名只能返回voidInteger或者int
  2. 更新查询必须是事务性的,标记为 @Transactional
  3. Spring Data 将删除所有未刷新的更改EntityManager,更改为@Modifying(clearAutomatically=false)

正如第二点所说的@Modifying查询必须有@Transactional(readOnly=false),所以我们可以在@Service方法调用@Repository级别或方法级别调用中添加它。如果在@Service级别添加它也适用于@Respository@Service级别方法调用中调用的方法?

例子:

@Service
class AnimalServiceImpl implements AnimalService {

@Autowire
AnimalRepository animalRepository;

@Override
@Transactional
public void persistAnimal() {
....
animalRepository.save();
}

@Override
@Transactional(readOnly = true)
public void checkIfAnimalPresent() {

...
animalRepository.checkIfPresent();

}

@Override
@Transactional
public void deleteAnimal() {
...
animalRepository.deleteAnimal();
}
}
Run Code Online (Sandbox Code Playgroud)

存储库

@Repository
@Transactional(readOnly=true)
public interface AnimalRepository extends org.springframework.data.repository.Repository {

@Modifying
@Query(...)
void save();

@Modifying
@Query(...)
int checkIfPresent() 

@Modifing
@Query(..)
int deleteAnimal();
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:

  1. @Transactional当我们在存储库@Repository级别拥有它并且我拥有@Modifying修改实体并将其写入数据库的方法(仅因为我@Transactional(readOnly = true)在类级别拥有)时,为什么我们需要在服务类中?
  2. @TransactionalService 类上的注释是否会传播到@Repository类?

我希望我在这里的问题和例子非常清楚。

小智 10

这是如何@Transactional工作的:

默认情况下,存储库实例上的 CRUD 方法是事务性的。
对于读取操作,事务配置readOnly标志设置为true
所有其他人都使用普通配置,@Transactional以便应用默认事务配置。
如果您需要为存储库中声明的方法之一调整事务配置,您可以覆盖该方法并添加@Transactional具有所需属性值的注释。

改变事务行为的另一种方法是使用(通常)覆盖多个存储库的外观或服务实现。
其目的是为非 CRUD 操作定义事务边界。

如果您使用这种方法,那么存储库中的事务配置将被忽略,因为外部事务(在服务层中定义)配置决定了实际使用的事务。

参考:Spring Data JPA - 参考文档 - 5.7。交易性